Skip to content

Commit b50d86f

Browse files
committed
Implemented IMU reads. Untested.
1 parent c8c1c6a commit b50d86f

File tree

6 files changed

+101
-3
lines changed

6 files changed

+101
-3
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ Cargo.lock
88

99
# Rustfmt backup files
1010
*.bk
11+
# Astyle backup files
12+
*.orig

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ readme = "README.md"
1313
measurements = "0.4.0"
1414
i2cdev = "0.3.1"
1515
byteorder = "1.0.0"
16+
libc = "0.2.0"
1617

1718
[build-dependencies]
1819
gcc = "0.3"

examples/get_all.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,9 @@ fn main() {
1616
println!("It's {} relative humidity", rh);
1717
let pressure = sense_hat.get_pressure().expect("Couldn't get pressure");
1818
println!("The pressure is {}", pressure);
19+
loop {
20+
let orientation = sense_hat.get_orientation_degrees().expect("Couldn't get orientation");
21+
println!("The orientation is {:?}", orientation);
22+
::std::thread::sleep(::std::time::Duration::from_millis(500));
23+
}
1924
}

src/lib.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
extern crate byteorder;
22
extern crate i2cdev;
33
extern crate measurements;
4+
extern crate libc;
45

56
pub use measurements::Temperature;
67
pub use measurements::Pressure;
@@ -18,14 +19,24 @@ pub struct RelativeHumidity {
1819
value: f64,
1920
}
2021

22+
/// Represents an orientation from the IMU
23+
#[derive(Debug, Copy, Clone)]
24+
pub struct OrientationDegrees {
25+
pub roll: f64,
26+
pub pitch: f64,
27+
pub yaw: f64
28+
}
29+
2130
/// Represents the SenseHat itself
2231
pub struct SenseHat<'a> {
23-
// LPS25H pressure sensor
32+
/// LPS25H pressure sensor
2433
pressure_chip: lps25h::Lps25h<LinuxI2CDevice>,
25-
// HTS221 humidity sensor
34+
/// HTS221 humidity sensor
2635
humidity_chip: hts221::Hts221<LinuxI2CDevice>,
27-
// LSM9DS1 IMU device
36+
/// LSM9DS1 IMU device
2837
accelerometer_chip: lsm9ds1::Lsm9ds1<'a>,
38+
/// Cached data
39+
orientation: OrientationDegrees,
2940
}
3041

3142
/// Errors that this crate can return
@@ -50,6 +61,7 @@ impl<'a> SenseHat<'a> {
5061
humidity_chip: hts221::Hts221::new(LinuxI2CDevice::new("/dev/i2c-1", 0x5f)?)?,
5162
pressure_chip: lps25h::Lps25h::new(LinuxI2CDevice::new("/dev/i2c-1", 0x5c)?)?,
5263
accelerometer_chip: lsm9ds1::Lsm9ds1::new()?,
64+
orientation: OrientationDegrees { roll: 0.0, pitch: 0.0, yaw: 0.0 },
5365
})
5466
}
5567

@@ -97,6 +109,15 @@ impl<'a> SenseHat<'a> {
97109
Err(SenseHatError::NotReady)
98110
}
99111
}
112+
113+
/// Returns a vector representing the current orientation.
114+
/// The values are in radians.
115+
pub fn get_orientation_degrees(&mut self) -> SenseHatResult<OrientationDegrees> {
116+
if self.accelerometer_chip.imu_read() {
117+
self.orientation = self.accelerometer_chip.get_imu_data()?;
118+
}
119+
Ok(self.orientation)
120+
}
100121
}
101122

102123
impl From<LinuxI2CError> for SenseHatError {

src/lsm9ds1.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,26 @@
1212
//! undone on drop.
1313
1414

15+
use super::OrientationDegrees;
16+
use libc;
17+
1518
enum RTIMULibContext {}
1619

1720
extern "C" {
1821
fn rtimulib_wrapper_create() -> *mut RTIMULibContext;
1922
fn rtimulib_wrapper_destroy(p_context: *mut RTIMULibContext);
23+
fn rtimulib_wrapper_imu_read(p_context: *mut RTIMULibContext) -> libc::c_int;
24+
fn rtimulib_wrapper_get_imu_data(p_context: *mut RTIMULibContext, orientation: *mut COrientation) -> libc::c_int;
25+
}
26+
27+
#[repr(C)]
28+
struct COrientation {
29+
x: libc::c_double,
30+
y: libc::c_double,
31+
z: libc::c_double
2032
}
2133

34+
2235
#[derive(Debug)]
2336
pub enum Error {
2437
RTIMULibError,
@@ -28,6 +41,7 @@ pub struct Lsm9ds1<'a> {
2841
rtimulib_ref: &'a mut RTIMULibContext,
2942
}
3043

44+
3145
impl<'a> Lsm9ds1<'a> {
3246
/// Uses the RTIMULib library.
3347
pub fn new() -> Result<Lsm9ds1<'a>, Error> {
@@ -42,6 +56,39 @@ impl<'a> Lsm9ds1<'a> {
4256

4357
Ok(Lsm9ds1 { rtimulib_ref: ctx_ref })
4458
}
59+
60+
/// Make the IMU do some work. When this function returns true, the IMU
61+
/// has data we can fetch with `get_imu_data()`.
62+
pub fn imu_read(&mut self) -> bool {
63+
let result = unsafe {
64+
rtimulib_wrapper_imu_read(self.rtimulib_ref)
65+
};
66+
return result == 0;
67+
}
68+
69+
pub fn get_imu_data(&mut self) -> Result<OrientationDegrees, Error> {
70+
let mut storage = COrientation {
71+
x: 0.0,
72+
y: 0.0,
73+
z: 0.0
74+
};
75+
let result = unsafe {
76+
rtimulib_wrapper_get_imu_data(self.rtimulib_ref, &mut storage)
77+
};
78+
if result == 1 {
79+
Ok(OrientationDegrees {
80+
roll: radians_to_degrees(storage.x),
81+
pitch: radians_to_degrees(storage.y),
82+
yaw: radians_to_degrees(storage.z),
83+
})
84+
} else {
85+
Err(Error::RTIMULibError)
86+
}
87+
}
88+
}
89+
90+
fn radians_to_degrees(radians: f64) -> f64 {
91+
360.0 * (radians / (::std::f64::consts::PI * 2.0))
4592
}
4693

4794
impl<'a> Drop for Lsm9ds1<'a> {

src/rtimulib_wrapper.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,17 @@ struct WrapperContext {
88
uint32_t magic;
99
};
1010

11+
struct Orientation {
12+
double x;
13+
double y;
14+
double z;
15+
};
16+
1117
extern "C" {
1218
WrapperContext* rtimulib_wrapper_create(void);
1319
void rtimulib_wrapper_destroy(WrapperContext* p_context);
20+
int rtimulib_wrapper_imu_read(WrapperContext* p_context);
21+
int rtimulib_wrapper_get_imu_data(WrapperContext* p_context, Orientation* p_output);
1422
}
1523

1624
WrapperContext* rtimulib_wrapper_create(void) {
@@ -33,3 +41,17 @@ void rtimulib_wrapper_destroy(WrapperContext* p_context) {
3341
delete p_context->p_imu;
3442
delete p_context;
3543
}
44+
45+
int rtimulib_wrapper_imu_read(WrapperContext* p_context) {
46+
return p_context->p_imu->IMURead();
47+
}
48+
49+
int rtimulib_wrapper_get_imu_data(WrapperContext* p_context, Orientation* p_output) {
50+
RTIMU_DATA imuData = p_context->p_imu->getIMUData();
51+
if (imuData.fusionPoseValid && p_output) {
52+
p_output->x = imuData.fusionPose.x();
53+
p_output->y = imuData.fusionPose.y();
54+
p_output->z = imuData.fusionPose.z();
55+
};
56+
return imuData.fusionPoseValid;
57+
}

0 commit comments

Comments
 (0)