-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* hiwonder imu setup * working hiwonder imu rust code * minor * rearrange to lib and log * hiwonder imu, refactor and return data as struct * working python binding draft for hiwonder IMU * hiwonder publish * separate version * update publish flow * update python bindings * fix hiwonder python * lint * update publish workflow * update readme --------- Co-authored-by: Wesley Maa <[email protected]>
- Loading branch information
1 parent
00bb5a6
commit cd1c664
Showing
15 changed files
with
603 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,12 @@ members = [ | |
"imu", | ||
"imu/bindings", | ||
"imu/hexmove", | ||
"imu/hiwonder", | ||
] | ||
resolver = "2" | ||
|
||
[workspace.package] | ||
|
||
version = "0.1.6" | ||
version = "0.1.7" | ||
authors = ["Wesley Maa <[email protected]>"] | ||
edition = "2021" | ||
description = "IMU package" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
"""Example usage of the Hiwonder IMU.""" | ||
|
||
import time | ||
|
||
from imu import HiwonderImu | ||
|
||
|
||
def main() -> None: | ||
# Create IMU instance | ||
imu = HiwonderImu("/dev/ttyUSB0", 9600) | ||
|
||
try: | ||
while True: | ||
if data := imu.read_data(): | ||
acc, gyro, angle = data | ||
print("\033[2J\033[H") # Clear screen | ||
print(f"Acceleration (m/s²): {acc}") | ||
print(f"Gyroscope (deg/s): {gyro}") | ||
print(f"Angle (degrees): {angle}") | ||
time.sleep(0.1) # Add small delay to make output readable | ||
except KeyboardInterrupt: | ||
print("\nExiting...") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
"""Defines the top-level API for the IMU package.""" | ||
|
||
from .bindings import ( | ||
HiwonderImu, | ||
PyHexmoveImuData as HexmoveImuData, | ||
PyHexmoveImuReader as HexmoveImuReader, | ||
) | ||
|
||
__all__ = ["HexmoveImuData", "HexmoveImuReader", "HiwonderImu"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
use hexmove::{ImuData as HexmoveImuData, ImuReader as HexmoveImuReader}; | ||
use pyo3::prelude::*; | ||
use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods}; | ||
use std::sync::{Arc, Mutex}; | ||
|
||
#[gen_stub_pyclass] | ||
#[pyclass] | ||
pub struct PyHexmoveImuReader { | ||
inner: Arc<Mutex<HexmoveImuReader>>, | ||
} | ||
|
||
#[gen_stub_pymethods] | ||
#[pymethods] | ||
impl PyHexmoveImuReader { | ||
#[new] | ||
fn new(interface: String, serial_number: u8, model: u8) -> PyResult<Self> { | ||
let imu_reader = HexmoveImuReader::new(&interface, serial_number, model) | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
Ok(PyHexmoveImuReader { | ||
inner: Arc::new(Mutex::new(imu_reader)), | ||
}) | ||
} | ||
|
||
fn get_data(&self) -> PyResult<PyHexmoveImuData> { | ||
let imu_reader = self | ||
.inner | ||
.lock() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
let data = imu_reader | ||
.get_data() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
Ok(PyHexmoveImuData::from(data)) | ||
} | ||
|
||
fn get_angles(&self) -> PyResult<(f32, f32, f32)> { | ||
let imu_reader = self | ||
.inner | ||
.lock() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
let (x, y, z) = imu_reader | ||
.get_angles() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
Ok((x, y, z)) | ||
} | ||
|
||
fn get_velocities(&self) -> PyResult<(f32, f32, f32)> { | ||
let imu_reader = self | ||
.inner | ||
.lock() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
let (x, y, z) = imu_reader | ||
.get_velocities() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
Ok((x, y, z)) | ||
} | ||
|
||
fn get_accelerations(&self) -> PyResult<(f32, f32, f32)> { | ||
let imu_reader = self | ||
.inner | ||
.lock() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
let (x, y, z) = imu_reader | ||
.get_accelerations() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
Ok((x, y, z)) | ||
} | ||
|
||
fn get_quaternion(&self) -> PyResult<(f32, f32, f32, f32)> { | ||
let imu_reader = self | ||
.inner | ||
.lock() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
let (w, x, y, z) = imu_reader | ||
.get_quaternion() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
Ok((w, x, y, z)) | ||
} | ||
|
||
#[pyo3(signature = (duration_ms=None, max_retries=None, max_variance=None))] | ||
fn zero_imu( | ||
&self, | ||
duration_ms: Option<u64>, | ||
max_retries: Option<u32>, | ||
max_variance: Option<f32>, | ||
) -> PyResult<()> { | ||
let imu_reader = self.inner.lock().unwrap(); | ||
imu_reader | ||
.zero_imu(duration_ms, max_retries, max_variance) | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e)) | ||
} | ||
|
||
fn stop(&self) -> PyResult<()> { | ||
let imu_reader = self | ||
.inner | ||
.lock() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
imu_reader | ||
.stop() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[gen_stub_pyclass] | ||
#[pyclass] | ||
#[derive(Clone)] | ||
pub struct PyHexmoveImuData { | ||
#[pyo3(get)] | ||
x_angle: f32, | ||
#[pyo3(get)] | ||
y_angle: f32, | ||
#[pyo3(get)] | ||
z_angle: f32, | ||
#[pyo3(get)] | ||
x_velocity: f32, | ||
#[pyo3(get)] | ||
y_velocity: f32, | ||
#[pyo3(get)] | ||
z_velocity: f32, | ||
#[pyo3(get)] | ||
x_angle_offset: f32, | ||
#[pyo3(get)] | ||
y_angle_offset: f32, | ||
#[pyo3(get)] | ||
z_angle_offset: f32, | ||
#[pyo3(get)] | ||
accel_x: f32, | ||
#[pyo3(get)] | ||
accel_y: f32, | ||
#[pyo3(get)] | ||
accel_z: f32, | ||
#[pyo3(get)] | ||
qw: f32, | ||
#[pyo3(get)] | ||
qx: f32, | ||
#[pyo3(get)] | ||
qy: f32, | ||
#[pyo3(get)] | ||
qz: f32, | ||
} | ||
|
||
impl From<HexmoveImuData> for PyHexmoveImuData { | ||
fn from(data: HexmoveImuData) -> Self { | ||
PyHexmoveImuData { | ||
x_angle: data.x_angle, | ||
y_angle: data.y_angle, | ||
z_angle: data.z_angle, | ||
x_velocity: data.x_velocity, | ||
y_velocity: data.y_velocity, | ||
z_velocity: data.z_velocity, | ||
x_angle_offset: data.x_angle_offset, | ||
y_angle_offset: data.y_angle_offset, | ||
z_angle_offset: data.z_angle_offset, | ||
accel_x: data.accel_x, | ||
accel_y: data.accel_y, | ||
accel_z: data.accel_z, | ||
qw: data.qw, | ||
qx: data.qx, | ||
qy: data.qy, | ||
qz: data.qz, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use hiwonder::IMU; | ||
use pyo3::prelude::*; | ||
use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods}; | ||
use std::sync::{Arc, Mutex}; | ||
|
||
#[gen_stub_pyclass] | ||
#[pyclass(name = "HiwonderImu")] | ||
pub struct PyHiwonderImu { | ||
inner: Arc<Mutex<IMU>>, | ||
} | ||
|
||
#[gen_stub_pymethods] | ||
#[pymethods] | ||
impl PyHiwonderImu { | ||
#[new] | ||
fn new(interface: String, baud_rate: u32) -> PyResult<Self> { | ||
let imu = IMU::new(&interface, baud_rate) | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
Ok(PyHiwonderImu { | ||
inner: Arc::new(Mutex::new(imu)), | ||
}) | ||
} | ||
|
||
fn read_data(&mut self) -> PyResult<Option<([f32; 3], [f32; 3], [f32; 3])>> { | ||
let mut imu = self | ||
.inner | ||
.lock() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?; | ||
imu.read_data() | ||
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string())) | ||
} | ||
} |
Oops, something went wrong.