new file: Legs_controller.py modified: README.md new file: __pycache__/Legs_controller.cpython-310.pyc new file: __pycache__/Legs_controller.cpython-313.pyc new file: __pycache__/balance.cpython-310.pyc new file: __pycache__/gradio.cpython-310.pyc new file: __pycache__/gradio.cpython-313.pyc new file: app_ui.py new file: balance.py new file: build/.cmake/api/v1/query/client-vscode/query.json new file: build/.cmake/api/v1/reply/cache-v2-ae4a9db768b4bbb36baa.json new file: build/.cmake/api/v1/reply/cmakeFiles-v1-389eb8769a8295e7571d.json new file: build/.cmake/api/v1/reply/codemodel-v2-5ea8cfc0b9263cbe5ae5.json new file: build/.cmake/api/v1/reply/directory-.-Debug-f5ebdc15457944623624.json new file: build/.cmake/api/v1/reply/index-2025-09-11T04-53-20-0515.json new file: build/.cmake/api/v1/reply/target-imu_py-Debug-3913d741f2156d7faae9.json new file: build/.cmake/api/v1/reply/toolchains-v1-3105704d088db7adbfb5.json new file: build/CMakeCache.txt new file: build/CMakeFiles/3.22.1/CMakeCXXCompiler.cmake new file: build/CMakeFiles/3.22.1/CMakeDetermineCompilerABI_CXX.bin new file: build/CMakeFiles/3.22.1/CMakeSystem.cmake new file: build/CMakeFiles/3.22.1/CompilerIdCXX/CMakeCXXCompilerId.cpp new file: build/CMakeFiles/3.22.1/CompilerIdCXX/a.out new file: build/CMakeFiles/CMakeDirectoryInformation.cmake new file: build/CMakeFiles/CMakeOutput.log new file: build/CMakeFiles/Makefile.cmake new file: build/CMakeFiles/Makefile2 new file: build/CMakeFiles/TargetDirectories.txt new file: build/CMakeFiles/cmake.check_cache new file: build/CMakeFiles/imu_py.dir/DependInfo.cmake new file: build/CMakeFiles/imu_py.dir/build.make new file: build/CMakeFiles/imu_py.dir/cmake_clean.cmake new file: build/CMakeFiles/imu_py.dir/compiler_depend.make new file: build/CMakeFiles/imu_py.dir/compiler_depend.ts new file: build/CMakeFiles/imu_py.dir/depend.make new file: build/CMakeFiles/imu_py.dir/flags.make new file: build/CMakeFiles/imu_py.dir/link.txt new file: build/CMakeFiles/imu_py.dir/progress.make new file: build/CMakeFiles/progress.marks new file: build/Makefile new file: build/cmake_install.cmake new file: build/compile_commands.json new file: dm_imu/bsp_crc.cpp new file: dm_imu/bsp_crc.h new file: dm_imu/imu_data.csv new file: dm_imu/imu_driver.cpp new file: dm_imu/imu_driver.h new file: dm_imu/imu_plot.png new file: dm_imu/plot_imu.py new file: dm_imu/test_imu.cpp new file: imu_data.csv new file: pybind_imu/CMakeLists.txt new file: pybind_imu/README.md new file: pybind_imu/build/CMakeCache.txt new file: pybind_imu/build/CMakeFiles/3.22.1/CMakeCXXCompiler.cmake new file: pybind_imu/build/CMakeFiles/3.22.1/CMakeDetermineCompilerABI_CXX.bin new file: pybind_imu/build/CMakeFiles/3.22.1/CMakeSystem.cmake new file: pybind_imu/build/CMakeFiles/3.22.1/CompilerIdCXX/CMakeCXXCompilerId.cpp new file: pybind_imu/build/CMakeFiles/3.22.1/CompilerIdCXX/a.out new file: pybind_imu/build/CMakeFiles/CMakeDirectoryInformation.cmake new file: pybind_imu/build/CMakeFiles/CMakeOutput.log new file: pybind_imu/build/CMakeFiles/Makefile.cmake new file: pybind_imu/build/CMakeFiles/Makefile2 new file: pybind_imu/build/CMakeFiles/TargetDirectories.txt new file: pybind_imu/build/CMakeFiles/cmake.check_cache new file: pybind_imu/build/CMakeFiles/imu_py.dir/DependInfo.cmake new file: pybind_imu/build/CMakeFiles/imu_py.dir/build.make new file: pybind_imu/build/CMakeFiles/imu_py.dir/cmake_clean.cmake new file: pybind_imu/build/CMakeFiles/imu_py.dir/compiler_depend.make new file: pybind_imu/build/CMakeFiles/imu_py.dir/compiler_depend.ts new file: pybind_imu/build/CMakeFiles/imu_py.dir/depend.make new file: pybind_imu/build/CMakeFiles/imu_py.dir/flags.make new file: pybind_imu/build/CMakeFiles/imu_py.dir/home/allenyuan/balance/dm_imu/bsp_crc.cpp.o new file: pybind_imu/build/CMakeFiles/imu_py.dir/home/allenyuan/balance/dm_imu/bsp_crc.cpp.o.d new file: pybind_imu/build/CMakeFiles/imu_py.dir/home/allenyuan/balance/dm_imu/imu_driver.cpp.o new file: pybind_imu/build/CMakeFiles/imu_py.dir/home/allenyuan/balance/dm_imu/imu_driver.cpp.o.d new file: pybind_imu/build/CMakeFiles/imu_py.dir/link.txt new file: pybind_imu/build/CMakeFiles/imu_py.dir/progress.make new file: pybind_imu/build/CMakeFiles/imu_py.dir/pybind_imu.cpp.o new file: pybind_imu/build/CMakeFiles/imu_py.dir/pybind_imu.cpp.o.d new file: pybind_imu/build/CMakeFiles/progress.marks new file: pybind_imu/build/Makefile new file: pybind_imu/build/cmake_install.cmake new file: pybind_imu/build/imu_py.cpython-310-aarch64-linux-gnu.so new file: pybind_imu/example.py new file: pybind_imu/pybind_imu.cpp new file: src/example.py new file: test_imu new file: u2can/DM_CAN.py new file: u2can/DM_Motor_Test.py new file: u2can/LICENSE new file: u2can/README.md new file: u2can/__pycache__/DM_CAN.cpython-310.pyc new file: u2can/__pycache__/DM_CAN.cpython-312.pyc new file: u2can/__pycache__/DM_CAN.cpython-313.pyc new file: u2can/__pycache__/gradio.cpython-313.pyc new file: u2can/__pycache__/motor_interface.cpython-313.pyc new file: u2can/motor_interface.py new file: u2can/requirements.txt new file: ui.log
Pybind11 Wrapper for DM‑IMU Driver
Overview
This project provides a Python module that wraps the DmImu class from the dm_imu driver library using pybind11.
After building, you obtain a shared object (imu_py*.so) that can be imported in Python to control the IMU, start data acquisition, and retrieve sensor readings as a Python dict.
Prerequisites
| Requirement | Version / Notes |
|---|---|
| C++ compiler | GCC 11 (or newer) |
| CMake | ≥ 3.14 |
| Python | 3.8 – 3.12 (the build uses the interpreter found by CMake) |
| pybind11 | Installed via pip install pybind11 (the package provides the CMake config) |
| Serial port access | The user must have read/write permission for the device (e.g., /dev/ttyACM1). See Serial Port Permissions below. |
Build Steps
# 1. Install pybind11 (if not already installed)
pip install --user pybind11
# 2. Clone / copy this repository (already present in /home/allenyuan/balance)
# 3. Build the Python extension
cd pybind_imu
rm -rf build
mkdir build && cd build
cmake .. # CMake will locate pybind11 automatically
make -j$(nproc) # Builds imu_py.cpython-<ver>-<arch>.so
The compiled shared library will be placed in pybind_imu/build/.
Installing the Module (optional)
You can copy the generated .so file to a location that is on PYTHONPATH, for example:
cp build/imu_py.cpython-310-aarch64-linux-gnu.so ~/.local/lib/python3.10/site-packages/
cp build/imu_py.cpython-310-aarch64-linux-gnu.so /home/allenyuan/miniconda3/lib/python3.13/site-packages
Or simply import it directly from the build directory (see the example below).
Serial Port Permissions
If you encounter the error:
Failed to open IMU serial port: /dev/ttyACM1
you have two options:
-
Run the Python script with sudo (quick test):
sudo python3 example.py -
Add your user to the dialout group (recommended):
sudo usermod -aG dialout $USER # Log out and log back in for the group change to take effect
Usage from Python
import pathlib
import importlib.util
# Load the compiled module (adjust the path if you installed it elsewhere)
lib_path = pathlib.Path('pybind_imu/build/imu_py.cpython-310-aarch64-linux-gnu.so')
spec = importlib.util.spec_from_file_location('imu_py', lib_path)
imu_py = importlib.util.module_from_spec(spec)
spec.loader.exec_module(imu_py)
# Create an IMU instance (default port and baud rate are shown)
imu = imu_py.DmImu('/dev/ttyACM1', 921600)
# Start data acquisition (spawns a background thread)
imu.start()
# Retrieve a single measurement
data = imu.getData()
print('IMU data:', data)
# When finished, stop the thread and close the serial port
imu.stop()
Example Program
A ready‑to‑run example is provided as example.py in this directory. It demonstrates:
- Loading the module
- Starting the driver
- Reading data in a loop
- Clean shutdown on
KeyboardInterrupt
Run it with:
python3 example.py
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
CMake cannot find pybind11 |
pybind11 not installed or not on CMAKE_PREFIX_PATH |
pip install --user pybind11 and ensure CMAKE_PREFIX_PATH points to ~/.local/lib/python3.10/site-packages/pybind11/share/cmake (the CMakeLists already sets this). |
Compilation error: dm_imu/imu_driver.h: No such file or directory |
Include path wrong | The CMake file uses include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) which points to the project root where dm_imu resides. |
| Runtime: “Failed to open IMU serial port” | No permission on the device | Use sudo or add user to dialout group (see above). |
| Python import error “module not found” | Wrong path to the .so file |
Adjust lib_path in the Python code to point to the actual location of the compiled shared object. |
Enjoy! Feel free to adapt the wrapper for additional driver functionality or integrate it into larger Python applications. If you have any questions, open an issue in the repository or contact the maintainer.