* add initial lsm6ds3 setup

* accel works

* ignore lsm6ds3 in locationd

* add gyro

* add temp

Co-authored-by: Comma Device <device@comma.ai>
pull/2276/head
Willem Melching 5 years ago committed by GitHub
parent a09fd7c860
commit e51da619c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      selfdrive/locationd/locationd.py
  2. 3
      selfdrive/sensord/SConscript
  3. 8
      selfdrive/sensord/sensors/bmx055_magn.cc
  4. 62
      selfdrive/sensord/sensors/lsm6ds3_accel.cc
  5. 24
      selfdrive/sensord/sensors/lsm6ds3_accel.hpp
  6. 65
      selfdrive/sensord/sensors/lsm6ds3_gyro.cc
  7. 24
      selfdrive/sensord/sensors/lsm6ds3_gyro.hpp
  8. 45
      selfdrive/sensord/sensors/lsm6ds3_temp.cc
  9. 22
      selfdrive/sensord/sensors/lsm6ds3_temp.hpp
  10. 32
      selfdrive/sensord/sensors_qcom2.cc

@ -2,6 +2,7 @@
import numpy as np import numpy as np
import sympy as sp import sympy as sp
import cereal.messaging as messaging import cereal.messaging as messaging
from cereal import log
import common.transformations.coordinates as coord import common.transformations.coordinates as coord
from common.transformations.orientation import ecef_euler_from_ned, \ from common.transformations.orientation import ecef_euler_from_ned, \
euler_from_quat, \ euler_from_quat, \
@ -19,6 +20,8 @@ from selfdrive.swaglog import cloudlog
from sympy.utilities.lambdify import lambdify from sympy.utilities.lambdify import lambdify
from rednose.helpers.sympy_helpers import euler_rotate from rednose.helpers.sympy_helpers import euler_rotate
SensorSource = log.SensorEventData.SensorSource
VISION_DECIMATION = 2 VISION_DECIMATION = 2
SENSOR_DECIMATION = 10 SENSOR_DECIMATION = 10
@ -235,6 +238,10 @@ class Localizer():
def handle_sensors(self, current_time, log): def handle_sensors(self, current_time, log):
# TODO does not yet account for double sensor readings in the log # TODO does not yet account for double sensor readings in the log
for sensor_reading in log: for sensor_reading in log:
# TODO: handle messages from two IMUs at the same time
if sensor_reading.source == SensorSource.lsm6ds3:
continue
# Gyro Uncalibrated # Gyro Uncalibrated
if sensor_reading.sensor == 5 and sensor_reading.type == 16: if sensor_reading.sensor == 5 and sensor_reading.type == 16:
self.gyro_counter += 1 self.gyro_counter += 1

@ -13,5 +13,8 @@ else:
'sensors/bmx055_gyro.cc', 'sensors/bmx055_gyro.cc',
'sensors/bmx055_magn.cc', 'sensors/bmx055_magn.cc',
'sensors/bmx055_temp.cc', 'sensors/bmx055_temp.cc',
'sensors/lsm6ds3_accel.cc',
'sensors/lsm6ds3_gyro.cc',
'sensors/lsm6ds3_temp.cc',
] ]
env.Program('_sensord', ['sensors_qcom2.cc'] + sensors, LIBS=[common, cereal, messaging, 'capnp', 'zmq', 'kj']) env.Program('_sensord', ['sensors_qcom2.cc'] + sensors, LIBS=[common, cereal, messaging, 'capnp', 'zmq', 'kj'])

@ -6,22 +6,24 @@
#include "bmx055_magn.hpp" #include "bmx055_magn.hpp"
int16_t parse_xy(uint8_t lsb, uint8_t msb){ static int16_t parse_xy(uint8_t lsb, uint8_t msb){
// 13 bit // 13 bit
uint16_t combined = (uint16_t(msb) << 5) | uint16_t(lsb >> 3); uint16_t combined = (uint16_t(msb) << 5) | uint16_t(lsb >> 3);
return int16_t(combined << 3) / (1 << 3); return int16_t(combined << 3) / (1 << 3);
} }
int16_t parse_z(uint8_t lsb, uint8_t msb){ static int16_t parse_z(uint8_t lsb, uint8_t msb){
// 15 bit // 15 bit
uint16_t combined = (uint16_t(msb) << 7) | uint16_t(lsb >> 1); uint16_t combined = (uint16_t(msb) << 7) | uint16_t(lsb >> 1);
return int16_t(combined << 1) / (1 << 1); return int16_t(combined << 1) / (1 << 1);
} }
uint16_t parse_rhall(uint8_t lsb, uint8_t msb){ /*
static uint16_t parse_rhall(uint8_t lsb, uint8_t msb){
// 14 bit // 14 bit
return (uint16_t(msb) << 6) | uint16_t(lsb >> 2); return (uint16_t(msb) << 6) | uint16_t(lsb >> 2);
} }
*/
BMX055_Magn::BMX055_Magn(I2CBus *bus) : I2CSensor(bus) {} BMX055_Magn::BMX055_Magn(I2CBus *bus) : I2CSensor(bus) {}

@ -0,0 +1,62 @@
#include <cassert>
#include "common/swaglog.h"
#include "common/timing.h"
#include "lsm6ds3_accel.hpp"
LSM6DS3_Accel::LSM6DS3_Accel(I2CBus *bus) : I2CSensor(bus) {}
int LSM6DS3_Accel::init(){
int ret = 0;
uint8_t buffer[1];
ret = read_register(LSM6DS3_ACCEL_I2C_REG_ID, buffer, 1);
if(ret < 0){
LOGE("Reading chip ID failed: %d", ret);
goto fail;
}
if(buffer[0] != LSM6DS3_ACCEL_CHIP_ID){
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], LSM6DS3_ACCEL_CHIP_ID);
ret = -1;
goto fail;
}
// TODO: set scale and bandwith. Default is +- 2G, 50 Hz
ret = set_register(LSM6DS3_ACCEL_I2C_REG_CTRL1_XL, LSM6DS3_ACCEL_ODR_104HZ);
if (ret < 0){
goto fail;
}
fail:
return ret;
}
void LSM6DS3_Accel::get_event(cereal::SensorEventData::Builder &event){
uint64_t start_time = nanos_since_boot();
uint8_t buffer[6];
int len = read_register(LSM6DS3_ACCEL_I2C_REG_OUTX_L_XL, buffer, sizeof(buffer));
assert(len == sizeof(buffer));
float scale = 9.81 * 2.0f / (1 << 15);
float x = read_16_bit(buffer[0], buffer[1]) * scale;
float y = read_16_bit(buffer[2], buffer[3]) * scale;
float z = read_16_bit(buffer[4], buffer[5]) * scale;
event.setSource(cereal::SensorEventData::SensorSource::LSM6DS3);
event.setVersion(1);
event.setSensor(SENSOR_ACCELEROMETER);
event.setType(SENSOR_TYPE_ACCELEROMETER);
event.setTimestamp(start_time);
float xyz[] = {y, -x, z};
kj::ArrayPtr<const float> vs(&xyz[0], 3);
auto svec = event.initAcceleration();
svec.setV(vs);
svec.setStatus(true);
}

@ -0,0 +1,24 @@
#pragma once
#include "sensors/i2c_sensor.hpp"
// Address of the chip on the bus
#define LSM6DS3_ACCEL_I2C_ADDR 0x6A
// Registers of the chip
#define LSM6DS3_ACCEL_I2C_REG_ID 0x0F
#define LSM6DS3_ACCEL_I2C_REG_CTRL1_XL 0x10
#define LSM6DS3_ACCEL_I2C_REG_OUTX_L_XL 0x28
// Constants
#define LSM6DS3_ACCEL_CHIP_ID 0x69
#define LSM6DS3_ACCEL_ODR_104HZ (0b0100 << 4)
class LSM6DS3_Accel : public I2CSensor {
uint8_t get_device_address() {return LSM6DS3_ACCEL_I2C_ADDR;}
public:
LSM6DS3_Accel(I2CBus *bus);
int init();
void get_event(cereal::SensorEventData::Builder &event);
};

@ -0,0 +1,65 @@
#include <cassert>
#include <cmath>
#include "common/swaglog.h"
#include "common/timing.h"
#include "lsm6ds3_gyro.hpp"
#define DEG2RAD(x) ((x) * M_PI / 180.0)
LSM6DS3_Gyro::LSM6DS3_Gyro(I2CBus *bus) : I2CSensor(bus) {}
int LSM6DS3_Gyro::init(){
int ret = 0;
uint8_t buffer[1];
ret = read_register(LSM6DS3_GYRO_I2C_REG_ID, buffer, 1);
if(ret < 0){
LOGE("Reading chip ID failed: %d", ret);
goto fail;
}
if(buffer[0] != LSM6DS3_GYRO_CHIP_ID){
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], LSM6DS3_GYRO_CHIP_ID);
ret = -1;
goto fail;
}
// TODO: set scale. Default is +- 250 deg/s
ret = set_register(LSM6DS3_GYRO_I2C_REG_CTRL2_G, LSM6DS3_GYRO_ODR_104HZ);
if (ret < 0){
goto fail;
}
fail:
return ret;
}
void LSM6DS3_Gyro::get_event(cereal::SensorEventData::Builder &event){
uint64_t start_time = nanos_since_boot();
uint8_t buffer[6];
int len = read_register(LSM6DS3_GYRO_I2C_REG_OUTX_L_G, buffer, sizeof(buffer));
assert(len == sizeof(buffer));
float scale = 250.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::LSM6DS3);
event.setVersion(1);
event.setSensor(SENSOR_GYRO_UNCALIBRATED);
event.setType(SENSOR_TYPE_GYROSCOPE_UNCALIBRATED);
event.setTimestamp(start_time);
float xyz[] = {y, -x, z};
kj::ArrayPtr<const float> vs(&xyz[0], 3);
auto svec = event.initAcceleration();
svec.setV(vs);
svec.setStatus(true);
}

@ -0,0 +1,24 @@
#pragma once
#include "sensors/i2c_sensor.hpp"
// Address of the chip on the bus
#define LSM6DS3_GYRO_I2C_ADDR 0x6A
// Registers of the chip
#define LSM6DS3_GYRO_I2C_REG_ID 0x0F
#define LSM6DS3_GYRO_I2C_REG_CTRL2_G 0x11
#define LSM6DS3_GYRO_I2C_REG_OUTX_L_G 0x22
// Constants
#define LSM6DS3_GYRO_CHIP_ID 0x69
#define LSM6DS3_GYRO_ODR_104HZ (0b0100 << 4)
class LSM6DS3_Gyro : public I2CSensor {
uint8_t get_device_address() {return LSM6DS3_GYRO_I2C_ADDR;}
public:
LSM6DS3_Gyro(I2CBus *bus);
int init();
void get_event(cereal::SensorEventData::Builder &event);
};

@ -0,0 +1,45 @@
#include <cassert>
#include "common/swaglog.h"
#include "common/timing.h"
#include "lsm6ds3_temp.hpp"
LSM6DS3_Temp::LSM6DS3_Temp(I2CBus *bus) : I2CSensor(bus) {}
int LSM6DS3_Temp::init(){
int ret = 0;
uint8_t buffer[1];
ret = read_register(LSM6DS3_TEMP_I2C_REG_ID, buffer, 1);
if(ret < 0){
LOGE("Reading chip ID failed: %d", ret);
goto fail;
}
if(buffer[0] != LSM6DS3_TEMP_CHIP_ID){
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], LSM6DS3_TEMP_CHIP_ID);
ret = -1;
goto fail;
}
fail:
return ret;
}
void LSM6DS3_Temp::get_event(cereal::SensorEventData::Builder &event){
uint64_t start_time = nanos_since_boot();
uint8_t buffer[2];
int len = read_register(LSM6DS3_TEMP_I2C_REG_OUT_TEMP_L, buffer, sizeof(buffer));
assert(len == sizeof(buffer));
float temp = 25.0f + read_16_bit(buffer[0], buffer[1]) / 16.0f;
event.setSource(cereal::SensorEventData::SensorSource::LSM6DS3);
event.setVersion(1);
event.setType(SENSOR_TYPE_AMBIENT_TEMPERATURE);
event.setTimestamp(start_time);
event.setTemperature(temp);
}

@ -0,0 +1,22 @@
#pragma once
#include "sensors/i2c_sensor.hpp"
// Address of the chip on the bus
#define LSM6DS3_TEMP_I2C_ADDR 0x6A
// Registers of the chip
#define LSM6DS3_TEMP_I2C_REG_ID 0x0F
#define LSM6DS3_TEMP_I2C_REG_OUT_TEMP_L 0x20
// Constants
#define LSM6DS3_TEMP_CHIP_ID 0x69
class LSM6DS3_Temp : public I2CSensor {
uint8_t get_device_address() {return LSM6DS3_TEMP_I2C_ADDR;}
public:
LSM6DS3_Temp(I2CBus *bus);
int init();
void get_event(cereal::SensorEventData::Builder &event);
};

@ -11,10 +11,16 @@
#include "sensors/sensor.hpp" #include "sensors/sensor.hpp"
#include "sensors/constants.hpp" #include "sensors/constants.hpp"
#include "sensors/bmx055_accel.hpp" #include "sensors/bmx055_accel.hpp"
#include "sensors/bmx055_gyro.hpp" #include "sensors/bmx055_gyro.hpp"
#include "sensors/bmx055_magn.hpp" #include "sensors/bmx055_magn.hpp"
#include "sensors/bmx055_temp.hpp" #include "sensors/bmx055_temp.hpp"
#include "sensors/lsm6ds3_accel.hpp"
#include "sensors/lsm6ds3_gyro.hpp"
#include "sensors/lsm6ds3_temp.hpp"
#include "sensors/light_sensor.hpp" #include "sensors/light_sensor.hpp"
volatile sig_atomic_t do_exit = 0; volatile sig_atomic_t do_exit = 0;
@ -36,18 +42,28 @@ int sensor_loop() {
return -1; return -1;
} }
BMX055_Accel accel(i2c_bus_imu); BMX055_Accel bmx055_accel(i2c_bus_imu);
BMX055_Gyro gyro(i2c_bus_imu); BMX055_Gyro bmx055_gyro(i2c_bus_imu);
BMX055_Magn magn(i2c_bus_imu); BMX055_Magn bmx055_magn(i2c_bus_imu);
BMX055_Temp temp(i2c_bus_imu); BMX055_Temp bmx055_temp(i2c_bus_imu);
LSM6DS3_Accel lsm6ds3_accel(i2c_bus_imu);
LSM6DS3_Gyro lsm6ds3_gyro(i2c_bus_imu);
LSM6DS3_Temp lsm6ds3_temp(i2c_bus_imu);
LightSensor light("/sys/class/i2c-adapter/i2c-2/2-0038/iio:device1/in_intensity_both_raw"); LightSensor light("/sys/class/i2c-adapter/i2c-2/2-0038/iio:device1/in_intensity_both_raw");
// Sensor init // Sensor init
std::vector<Sensor *> sensors; std::vector<Sensor *> sensors;
sensors.push_back(&accel); sensors.push_back(&bmx055_accel);
sensors.push_back(&gyro); sensors.push_back(&bmx055_gyro);
sensors.push_back(&magn); sensors.push_back(&bmx055_magn);
sensors.push_back(&temp); sensors.push_back(&bmx055_temp);
sensors.push_back(&lsm6ds3_accel);
sensors.push_back(&lsm6ds3_gyro);
sensors.push_back(&lsm6ds3_temp);
sensors.push_back(&light); sensors.push_back(&light);

Loading…
Cancel
Save