Tici sensord (#2072)
* tici sensord: WIP * add sensor constants * rename files * base class * init sensors * publish something * dont leak memory * try reading from accel * Accel works * add time and sensor source * Update release files * If we want low BW we want 125hz * this should run gyro as well * add filter on gyro * also filter accel data * Add i2c files * cast makes macos unhappy * Same outputs as android sensord Co-authored-by: Tici <robbe@comma.ai> Co-authored-by: Willem Melching <willem.melching@gmail.com>pull/2086/head
parent
521b6688ea
commit
622e42d504
17 changed files with 559 additions and 8 deletions
@ -0,0 +1,80 @@ |
|||||||
|
#include "i2c.h" |
||||||
|
|
||||||
|
#include <cassert> |
||||||
|
#include <unistd.h> |
||||||
|
#include <stdexcept> |
||||||
|
#include <stdio.h> |
||||||
|
#include <fcntl.h> |
||||||
|
#include <sys/ioctl.h> |
||||||
|
#include "common/swaglog.h" |
||||||
|
|
||||||
|
#define UNUSED(x) (void)(x) |
||||||
|
|
||||||
|
#ifdef QCOM2 |
||||||
|
// TODO: decide if we want to isntall libi2c-dev everywhere
|
||||||
|
#include <linux/i2c-dev.h> |
||||||
|
|
||||||
|
I2CBus::I2CBus(uint8_t bus_id){ |
||||||
|
char bus_name[20]; |
||||||
|
snprintf(bus_name, 20, "/dev/i2c-%d", bus_id); |
||||||
|
|
||||||
|
i2c_fd = open(bus_name, O_RDWR); |
||||||
|
if(i2c_fd < 0){ |
||||||
|
throw std::runtime_error("Failed to open I2C bus"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
I2CBus::~I2CBus(){ |
||||||
|
if(i2c_fd >= 0){ close(i2c_fd); } |
||||||
|
} |
||||||
|
|
||||||
|
int I2CBus::read_register(uint8_t device_address, uint register_address, uint8_t *buffer, uint8_t len){ |
||||||
|
int ret = 0; |
||||||
|
|
||||||
|
ret = ioctl(i2c_fd, I2C_SLAVE, device_address); |
||||||
|
if(ret < 0) { goto fail; } |
||||||
|
|
||||||
|
ret = i2c_smbus_read_i2c_block_data(i2c_fd, register_address, len, buffer); |
||||||
|
if((ret < 0) || (ret != len)) { goto fail; } |
||||||
|
|
||||||
|
fail: |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
int I2CBus::set_register(uint8_t device_address, uint register_address, uint8_t data){ |
||||||
|
int ret = 0; |
||||||
|
|
||||||
|
ret = ioctl(i2c_fd, I2C_SLAVE, device_address); |
||||||
|
if(ret < 0) { goto fail; } |
||||||
|
|
||||||
|
ret = i2c_smbus_write_byte_data(i2c_fd, register_address, data); |
||||||
|
if(ret < 0) { goto fail; } |
||||||
|
|
||||||
|
fail: |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
I2CBus::I2CBus(uint8_t bus_id){ |
||||||
|
UNUSED(bus_id); |
||||||
|
i2c_fd = -1; |
||||||
|
} |
||||||
|
|
||||||
|
I2CBus::~I2CBus(){} |
||||||
|
|
||||||
|
int I2CBus::read_register(uint8_t device_address, uint register_address, uint8_t *buffer, uint8_t len){ |
||||||
|
UNUSED(device_address); |
||||||
|
UNUSED(register_address); |
||||||
|
UNUSED(buffer); |
||||||
|
UNUSED(len); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
int I2CBus::set_register(uint8_t device_address, uint register_address, uint8_t data){ |
||||||
|
UNUSED(device_address); |
||||||
|
UNUSED(register_address); |
||||||
|
UNUSED(data); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,16 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include <sys/types.h> |
||||||
|
|
||||||
|
class I2CBus { |
||||||
|
private: |
||||||
|
int i2c_fd; |
||||||
|
|
||||||
|
public: |
||||||
|
I2CBus(uint8_t bus_id); |
||||||
|
~I2CBus(); |
||||||
|
|
||||||
|
int read_register(uint8_t device_address, uint register_address, uint8_t *buffer, uint8_t len); |
||||||
|
int set_register(uint8_t device_address, uint register_address, uint8_t data); |
||||||
|
}; |
@ -1,5 +1,14 @@ |
|||||||
Import('env', 'common', 'cereal', 'messaging') |
Import('env', 'arch', 'common', 'cereal', 'messaging') |
||||||
env.Program('_sensord', 'sensors.cc', LIBS=['hardware', common, cereal, messaging, 'capnp', 'zmq', 'kj']) |
if arch == "aarch64": |
||||||
lenv = env.Clone() |
env.Program('_sensord', 'sensors_qcom.cc', LIBS=['hardware', common, cereal, messaging, 'capnp', 'zmq', 'kj']) |
||||||
lenv['LIBPATH'] += ['/system/vendor/lib64'] |
lenv = env.Clone() |
||||||
lenv.Program('_gpsd', ['gpsd.cc'], LIBS=['hardware', common, 'diag', 'time_genoff', cereal, messaging, 'capnp', 'zmq', 'kj']) |
lenv['LIBPATH'] += ['/system/vendor/lib64'] |
||||||
|
lenv.Program('_gpsd', ['gpsd.cc'], LIBS=['hardware', common, 'diag', 'time_genoff', cereal, messaging, 'capnp', 'zmq', 'kj']) |
||||||
|
else: |
||||||
|
sensors = [ |
||||||
|
'sensors/i2c_sensor.cc', |
||||||
|
'sensors/bmx055_accel.cc', |
||||||
|
'sensors/bmx055_gyro.cc', |
||||||
|
'sensors/bmx055_magn.cc', |
||||||
|
] |
||||||
|
env.Program('_sensord', ['sensors_qcom2.cc'] + sensors, LIBS=[common, cereal, messaging, 'capnp', 'zmq', 'kj']) |
||||||
|
@ -0,0 +1,71 @@ |
|||||||
|
#include <cassert> |
||||||
|
#include "common/swaglog.h" |
||||||
|
#include "common/timing.h" |
||||||
|
|
||||||
|
#include "bmx055_accel.hpp" |
||||||
|
|
||||||
|
|
||||||
|
BMX055_Accel::BMX055_Accel(I2CBus *bus) : I2CSensor(bus) {} |
||||||
|
|
||||||
|
int BMX055_Accel::init(){ |
||||||
|
int ret = 0; |
||||||
|
uint8_t buffer[1]; |
||||||
|
|
||||||
|
ret = read_register(BMX055_ACCEL_I2C_REG_ID, buffer, 1); |
||||||
|
if(ret < 0){ |
||||||
|
LOGE("Reading chip ID failed: %d", ret); |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
if(buffer[0] != BMX055_ACCEL_CHIP_ID){ |
||||||
|
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], BMX055_ACCEL_CHIP_ID); |
||||||
|
ret = -1; |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
// High bandwidth
|
||||||
|
// ret = set_register(BMX055_ACCEL_I2C_REG_HBW, BMX055_ACCEL_HBW_ENABLE);
|
||||||
|
// if (ret < 0){
|
||||||
|
// goto fail;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Low bandwidth
|
||||||
|
ret = set_register(BMX055_ACCEL_I2C_REG_HBW, BMX055_ACCEL_HBW_DISABLE); |
||||||
|
if (ret < 0){ |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
ret = set_register(BMX055_ACCEL_I2C_REG_BW, BMX055_ACCEL_BW_125HZ); |
||||||
|
if (ret < 0){ |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
fail: |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void BMX055_Accel::get_event(cereal::SensorEventData::Builder &event){ |
||||||
|
uint64_t start_time = nanos_since_boot(); |
||||||
|
uint8_t buffer[6]; |
||||||
|
int len = read_register(BMX055_ACCEL_I2C_REG_FIFO, buffer, sizeof(buffer)); |
||||||
|
assert(len == 6); |
||||||
|
|
||||||
|
// 12 bit = +-2g
|
||||||
|
float scale = 9.81 * 2.0f / (1 << 11); |
||||||
|
float x = -read_12_bit(buffer[0], buffer[1]) * scale; |
||||||
|
float y = -read_12_bit(buffer[2], buffer[3]) * scale; |
||||||
|
float z = read_12_bit(buffer[4], buffer[5]) * scale; |
||||||
|
|
||||||
|
event.setSource(cereal::SensorEventData::SensorSource::BMX055); |
||||||
|
event.setVersion(1); |
||||||
|
event.setSensor(SENSOR_ACCELEROMETER); |
||||||
|
event.setType(SENSOR_TYPE_ACCELEROMETER); |
||||||
|
event.setTimestamp(start_time); |
||||||
|
|
||||||
|
float xyz[] = {x, y, z}; |
||||||
|
kj::ArrayPtr<const float> vs(&xyz[0], 3); |
||||||
|
|
||||||
|
auto svec = event.initAcceleration(); |
||||||
|
svec.setV(vs); |
||||||
|
svec.setStatus(true); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "sensors/i2c_sensor.hpp" |
||||||
|
|
||||||
|
// Address of the chip on the bus
|
||||||
|
#define BMX055_ACCEL_I2C_ADDR 0x18 |
||||||
|
|
||||||
|
// Registers of the chip
|
||||||
|
#define BMX055_ACCEL_I2C_REG_ID 0x00 |
||||||
|
#define BMX055_ACCEL_I2C_REG_BW 0x10 |
||||||
|
#define BMX055_ACCEL_I2C_REG_HBW 0x13 |
||||||
|
#define BMX055_ACCEL_I2C_REG_FIFO 0x3F |
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define BMX055_ACCEL_CHIP_ID 0xFA |
||||||
|
|
||||||
|
#define BMX055_ACCEL_HBW_ENABLE 0b10000000 |
||||||
|
#define BMX055_ACCEL_HBW_DISABLE 0b00000000 |
||||||
|
|
||||||
|
#define BMX055_ACCEL_BW_7_81HZ 0b01000 |
||||||
|
#define BMX055_ACCEL_BW_15_63HZ 0b01001 |
||||||
|
#define BMX055_ACCEL_BW_31_25HZ 0b01010 |
||||||
|
#define BMX055_ACCEL_BW_62_5HZ 0b01011 |
||||||
|
#define BMX055_ACCEL_BW_125HZ 0b01100 |
||||||
|
#define BMX055_ACCEL_BW_250HZ 0b01101 |
||||||
|
#define BMX055_ACCEL_BW_500HZ 0b01110 |
||||||
|
#define BMX055_ACCEL_BW_1000HZ 0b01111 |
||||||
|
|
||||||
|
class BMX055_Accel : public I2CSensor { |
||||||
|
uint8_t get_device_address() {return BMX055_ACCEL_I2C_ADDR;} |
||||||
|
public: |
||||||
|
BMX055_Accel(I2CBus *bus); |
||||||
|
int init(); |
||||||
|
void get_event(cereal::SensorEventData::Builder &event); |
||||||
|
}; |
@ -0,0 +1,81 @@ |
|||||||
|
#include <cassert> |
||||||
|
#include <cmath> |
||||||
|
#include "common/swaglog.h" |
||||||
|
|
||||||
|
#include "bmx055_gyro.hpp" |
||||||
|
|
||||||
|
#define DEG2RAD(x) ((x) * M_PI / 180.0) |
||||||
|
|
||||||
|
|
||||||
|
BMX055_Gyro::BMX055_Gyro(I2CBus *bus) : I2CSensor(bus) {} |
||||||
|
|
||||||
|
int BMX055_Gyro::init(){ |
||||||
|
int ret = 0; |
||||||
|
uint8_t buffer[1]; |
||||||
|
|
||||||
|
ret =read_register(BMX055_GYRO_I2C_REG_ID, buffer, 1); |
||||||
|
if(ret < 0){ |
||||||
|
LOGE("Reading chip ID failed: %d", ret); |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
if(buffer[0] != BMX055_GYRO_CHIP_ID){ |
||||||
|
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], BMX055_GYRO_CHIP_ID); |
||||||
|
ret = -1; |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
// High bandwidth
|
||||||
|
// ret = set_register(BMX055_GYRO_I2C_REG_HBW, BMX055_GYRO_HBW_ENABLE);
|
||||||
|
// if (ret < 0){
|
||||||
|
// goto fail;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Low bandwidth
|
||||||
|
ret = set_register(BMX055_GYRO_I2C_REG_HBW, BMX055_GYRO_HBW_DISABLE); |
||||||
|
if (ret < 0){ |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
// 116 Hz filter
|
||||||
|
ret = set_register(BMX055_GYRO_I2C_REG_BW, BMX055_GYRO_BW_116HZ); |
||||||
|
if (ret < 0){ |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
// +- 125 deg/s range
|
||||||
|
ret = set_register(BMX055_GYRO_I2C_REG_RANGE, BMX055_GYRO_RANGE_125); |
||||||
|
if (ret < 0){ |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
fail: |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void BMX055_Gyro::get_event(cereal::SensorEventData::Builder &event){ |
||||||
|
uint64_t start_time = nanos_since_boot(); |
||||||
|
uint8_t buffer[6]; |
||||||
|
int len = read_register(BMX055_GYRO_I2C_REG_FIFO, buffer, sizeof(buffer)); |
||||||
|
assert(len == 6); |
||||||
|
|
||||||
|
// 16 bit = +- 125 deg/s
|
||||||
|
float scale = 125.0f / (1 << 15); |
||||||
|
float x = -DEG2RAD(read_16_bit(buffer[0], buffer[1]) * scale); |
||||||
|
float y = -DEG2RAD(read_16_bit(buffer[2], buffer[3]) * scale); |
||||||
|
float z = DEG2RAD(read_16_bit(buffer[4], buffer[5]) * scale); |
||||||
|
|
||||||
|
event.setSource(cereal::SensorEventData::SensorSource::BMX055); |
||||||
|
event.setVersion(1); |
||||||
|
event.setSensor(SENSOR_GYRO_UNCALIBRATED); |
||||||
|
event.setType(SENSOR_TYPE_GYROSCOPE_UNCALIBRATED); |
||||||
|
event.setTimestamp(start_time); |
||||||
|
|
||||||
|
float xyz[] = {x, y, z}; |
||||||
|
kj::ArrayPtr<const float> vs(&xyz[0], 3); |
||||||
|
|
||||||
|
auto svec = event.initGyroUncalibrated(); |
||||||
|
svec.setV(vs); |
||||||
|
svec.setStatus(true); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "sensors/i2c_sensor.hpp" |
||||||
|
|
||||||
|
// Address of the chip on the bus
|
||||||
|
#define BMX055_GYRO_I2C_ADDR 0x68 |
||||||
|
|
||||||
|
// Registers of the chip
|
||||||
|
#define BMX055_GYRO_I2C_REG_ID 0x00 |
||||||
|
#define BMX055_GYRO_I2C_REG_RANGE 0x0F |
||||||
|
#define BMX055_GYRO_I2C_REG_BW 0x10 |
||||||
|
#define BMX055_GYRO_I2C_REG_HBW 0x13 |
||||||
|
#define BMX055_GYRO_I2C_REG_FIFO 0x3F |
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define BMX055_GYRO_CHIP_ID 0x0F |
||||||
|
|
||||||
|
#define BMX055_GYRO_HBW_ENABLE 0b10000000 |
||||||
|
#define BMX055_GYRO_HBW_DISABLE 0b00000000 |
||||||
|
|
||||||
|
#define BMX055_GYRO_RANGE_2000 0b000 |
||||||
|
#define BMX055_GYRO_RANGE_1000 0b001 |
||||||
|
#define BMX055_GYRO_RANGE_500 0b010 |
||||||
|
#define BMX055_GYRO_RANGE_250 0b011 |
||||||
|
#define BMX055_GYRO_RANGE_125 0b100 |
||||||
|
|
||||||
|
#define BMX055_GYRO_BW_116HZ 0b0010 |
||||||
|
|
||||||
|
|
||||||
|
class BMX055_Gyro : public I2CSensor { |
||||||
|
uint8_t get_device_address() {return BMX055_GYRO_I2C_ADDR;} |
||||||
|
public: |
||||||
|
BMX055_Gyro(I2CBus *bus); |
||||||
|
int init(); |
||||||
|
void get_event(cereal::SensorEventData::Builder &event); |
||||||
|
}; |
@ -0,0 +1,43 @@ |
|||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include "common/swaglog.h" |
||||||
|
|
||||||
|
#include "bmx055_magn.hpp" |
||||||
|
|
||||||
|
|
||||||
|
BMX055_Magn::BMX055_Magn(I2CBus *bus) : I2CSensor(bus) {} |
||||||
|
|
||||||
|
|
||||||
|
int BMX055_Magn::init(){ |
||||||
|
int ret; |
||||||
|
uint8_t buffer[1]; |
||||||
|
|
||||||
|
// suspend -> sleep
|
||||||
|
ret = set_register(BMX055_MAGN_I2C_REG_PWR_0, 0x01); |
||||||
|
if(ret < 0){ |
||||||
|
LOGE("Enabling power failed: %d", ret); |
||||||
|
return ret; |
||||||
|
} |
||||||
|
usleep(5 * 1000); // wait until the chip is powered on
|
||||||
|
|
||||||
|
// read chip ID
|
||||||
|
ret = read_register(BMX055_MAGN_I2C_REG_ID, buffer, 1); |
||||||
|
if(ret < 0){ |
||||||
|
LOGE("Reading chip ID failed: %d", ret); |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
if(buffer[0] != BMX055_MAGN_CHIP_ID){ |
||||||
|
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], BMX055_MAGN_CHIP_ID); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
// perform self-test
|
||||||
|
|
||||||
|
|
||||||
|
// sleep -> active (normal, high-precision)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "sensors/i2c_sensor.hpp" |
||||||
|
|
||||||
|
// Address of the chip on the bus
|
||||||
|
#define BMX055_MAGN_I2C_ADDR 0x10 |
||||||
|
|
||||||
|
// Registers of the chip
|
||||||
|
#define BMX055_MAGN_I2C_REG_ID 0x40 |
||||||
|
#define BMX055_MAGN_I2C_REG_PWR_0 0x4B |
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define BMX055_MAGN_CHIP_ID 0x32 |
||||||
|
|
||||||
|
class BMX055_Magn : public I2CSensor{ |
||||||
|
uint8_t get_device_address() {return BMX055_MAGN_I2C_ADDR;} |
||||||
|
public: |
||||||
|
BMX055_Magn(I2CBus *bus); |
||||||
|
int init(); |
||||||
|
void get_event(cereal::SensorEventData::Builder &event){}; |
||||||
|
}; |
@ -0,0 +1,17 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
|
||||||
|
#define SENSOR_ACCELEROMETER 1 |
||||||
|
#define SENSOR_MAGNETOMETER 2 |
||||||
|
#define SENSOR_MAGNETOMETER_UNCALIBRATED 3 |
||||||
|
#define SENSOR_GYRO 4 |
||||||
|
#define SENSOR_GYRO_UNCALIBRATED 5 |
||||||
|
#define SENSOR_LIGHT 7 |
||||||
|
|
||||||
|
#define SENSOR_TYPE_ACCELEROMETER 1 |
||||||
|
#define SENSOR_TYPE_GEOMAGNETIC_FIELD 2 |
||||||
|
#define SENSOR_TYPE_GYROSCOPE 4 |
||||||
|
#define SENSOR_TYPE_LIGHT 5 |
||||||
|
#define SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED 14 |
||||||
|
#define SENSOR_TYPE_MAGNETIC_FIELD SENSOR_TYPE_GEOMAGNETIC_FIELD |
||||||
|
#define SENSOR_TYPE_GYROSCOPE_UNCALIBRATED 16 |
@ -0,0 +1,24 @@ |
|||||||
|
#include <iostream> |
||||||
|
#include "i2c_sensor.hpp" |
||||||
|
|
||||||
|
int16_t read_12_bit(uint8_t lsb, uint8_t msb){ |
||||||
|
uint16_t combined = (uint16_t(msb) << 8) | uint16_t(lsb & 0xF0); |
||||||
|
return int16_t(combined) / (1 << 4); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t read_16_bit(uint8_t lsb, uint8_t msb){ |
||||||
|
uint16_t combined = (uint16_t(msb) << 8) | uint16_t(lsb); |
||||||
|
return int16_t(combined); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
I2CSensor::I2CSensor(I2CBus *bus) : bus(bus){ |
||||||
|
} |
||||||
|
|
||||||
|
int I2CSensor::read_register(uint register_address, uint8_t *buffer, uint8_t len){ |
||||||
|
return bus->read_register(get_device_address(), register_address, buffer, len); |
||||||
|
} |
||||||
|
|
||||||
|
int I2CSensor::set_register(uint register_address, uint8_t data){ |
||||||
|
return bus->set_register(get_device_address(), register_address, data); |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <cstdint> |
||||||
|
#include "cereal/gen/cpp/log.capnp.h" |
||||||
|
#include "common/i2c.h" |
||||||
|
#include "sensors/constants.hpp" |
||||||
|
|
||||||
|
int16_t read_12_bit(uint8_t lsb, uint8_t msb); |
||||||
|
int16_t read_16_bit(uint8_t lsb, uint8_t msb); |
||||||
|
|
||||||
|
|
||||||
|
class I2CSensor { |
||||||
|
private: |
||||||
|
I2CBus *bus; |
||||||
|
virtual uint8_t get_device_address() = 0; |
||||||
|
|
||||||
|
public: |
||||||
|
I2CSensor(I2CBus *bus); |
||||||
|
int read_register(uint register_address, uint8_t *buffer, uint8_t len); |
||||||
|
int set_register(uint register_address, uint8_t data); |
||||||
|
virtual int init() = 0; |
||||||
|
virtual void get_event(cereal::SensorEventData::Builder &event) = 0; |
||||||
|
}; |
@ -0,0 +1,86 @@ |
|||||||
|
#include <vector> |
||||||
|
#include <csignal> |
||||||
|
#include <chrono> |
||||||
|
#include <thread> |
||||||
|
#include <sys/resource.h> |
||||||
|
|
||||||
|
#include "messaging.hpp" |
||||||
|
#include "common/i2c.h" |
||||||
|
#include "common/timing.h" |
||||||
|
#include "common/swaglog.h" |
||||||
|
|
||||||
|
#include "sensors/constants.hpp" |
||||||
|
#include "sensors/bmx055_accel.hpp" |
||||||
|
#include "sensors/bmx055_gyro.hpp" |
||||||
|
#include "sensors/bmx055_magn.hpp" |
||||||
|
|
||||||
|
volatile sig_atomic_t do_exit = 0; |
||||||
|
|
||||||
|
#define I2C_BUS_IMU 1 |
||||||
|
|
||||||
|
|
||||||
|
void set_do_exit(int sig) { |
||||||
|
do_exit = 1; |
||||||
|
} |
||||||
|
|
||||||
|
int sensor_loop() { |
||||||
|
I2CBus *i2c_bus_imu; |
||||||
|
|
||||||
|
try { |
||||||
|
i2c_bus_imu = new I2CBus(I2C_BUS_IMU); |
||||||
|
} catch (std::exception &e) { |
||||||
|
LOGE("I2CBus init failed"); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
BMX055_Accel accel(i2c_bus_imu); |
||||||
|
BMX055_Gyro gyro(i2c_bus_imu); |
||||||
|
BMX055_Magn magn(i2c_bus_imu); |
||||||
|
|
||||||
|
// Sensor init
|
||||||
|
std::vector<I2CSensor *> sensors; |
||||||
|
sensors.push_back(&accel); |
||||||
|
sensors.push_back(&gyro); |
||||||
|
// sensors.push_back(&magn);
|
||||||
|
|
||||||
|
|
||||||
|
for (I2CSensor * sensor : sensors){ |
||||||
|
int err = sensor->init(); |
||||||
|
if (err < 0){ |
||||||
|
LOGE("Error initializing sensors"); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
PubMaster pm({"sensorEvents"}); |
||||||
|
|
||||||
|
while (!do_exit){ |
||||||
|
uint64_t log_time = nanos_since_boot(); |
||||||
|
|
||||||
|
capnp::MallocMessageBuilder msg; |
||||||
|
cereal::Event::Builder event = msg.initRoot<cereal::Event>(); |
||||||
|
event.setLogMonoTime(log_time); |
||||||
|
|
||||||
|
int num_events = sensors.size(); |
||||||
|
auto sensor_events = event.initSensorEvents(num_events); |
||||||
|
|
||||||
|
for (size_t i = 0; i < num_events; i++){ |
||||||
|
auto event = sensor_events[i]; |
||||||
|
sensors[i]->get_event(event); |
||||||
|
} |
||||||
|
|
||||||
|
pm.send("sensorEvents", msg); |
||||||
|
|
||||||
|
// TODO actually run at 100Hz
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, char *argv[]) { |
||||||
|
setpriority(PRIO_PROCESS, 0, -13); |
||||||
|
signal(SIGINT, set_do_exit); |
||||||
|
signal(SIGTERM, set_do_exit); |
||||||
|
|
||||||
|
return sensor_loop(); |
||||||
|
} |
Loading…
Reference in new issue