48 #define MAG_ROT_VAL_INTERNAL -1 49 #define CAL_ERROR_APPLY_CAL_MSG "FAILED APPLYING %s CAL #%u" 56 :
_parameters(parameters), _hil_enabled(hil_enabled)
58 for (
unsigned i = 0; i < 3; i++) {
132 for (
int topic_instance = 0; topic_instance <
MAG_COUNT_MAX; ++topic_instance) {
151 PX4_ERR(
"%s temp compensation init: failed to find device ID %u for instance %i",
"gyro", report.get().device_id,
171 PX4_ERR(
"%s temp compensation init: failed to find device ID %u for instance %i",
"accel", report.get().device_id,
191 PX4_ERR(
"%s temp compensation init: failed to find device ID %u for instance %i",
"baro", report.get().device_id,
206 unsigned gyro_count = 0;
207 unsigned accel_count = 0;
208 unsigned gyro_cal_found_count = 0;
209 unsigned accel_cal_found_count = 0;
212 for (
unsigned driver_index = 0; driver_index <
GYRO_COUNT_MAX; driver_index++) {
218 DevMgr::getHandle(str, h);
224 uint32_t driver_device_id = h.ioctl(DEVIOCGDEVICEID, 0);
225 bool config_ok =
false;
232 (void)sprintf(str,
"CAL_GYRO%u_ID", i);
236 (void)sprintf(str,
"CAL_GYRO%u_EN", i);
237 int32_t device_enabled = 1;
244 if (driver_index == 0 && device_id > 0) {
245 gyro_cal_found_count++;
249 if ((uint32_t)device_id == driver_device_id) {
256 (void)sprintf(str,
"CAL_GYRO%u_XOFF", i);
260 (void)sprintf(str,
"CAL_GYRO%u_YOFF", i);
264 (void)sprintf(str,
"CAL_GYRO%u_ZOFF", i);
268 (void)sprintf(str,
"CAL_GYRO%u_XSCALE", i);
272 (void)sprintf(str,
"CAL_GYRO%u_YSCALE", i);
276 (void)sprintf(str,
"CAL_GYRO%u_ZSCALE", i);
303 if (gyro_count < gyro_cal_found_count) {
309 (void)sprintf(str,
"CAL_GYRO%u_ID", i);
315 for (
unsigned driver_index = 0; driver_index <
ACCEL_COUNT_MAX; driver_index++) {
321 DevMgr::getHandle(str, h);
327 uint32_t driver_device_id = h.ioctl(DEVIOCGDEVICEID, 0);
328 bool config_ok =
false;
335 (void)sprintf(str,
"CAL_ACC%u_ID", i);
339 (void)sprintf(str,
"CAL_ACC%u_EN", i);
340 int32_t device_enabled = 1;
347 if (driver_index == 0 && device_id > 0) {
348 accel_cal_found_count++;
352 if ((uint32_t)device_id == driver_device_id) {
359 (void)sprintf(str,
"CAL_ACC%u_XOFF", i);
363 (void)sprintf(str,
"CAL_ACC%u_YOFF", i);
367 (void)sprintf(str,
"CAL_ACC%u_ZOFF", i);
371 (void)sprintf(str,
"CAL_ACC%u_XSCALE", i);
375 (void)sprintf(str,
"CAL_ACC%u_YSCALE", i);
379 (void)sprintf(str,
"CAL_ACC%u_ZSCALE", i);
406 if (accel_count < accel_cal_found_count) {
412 (void)sprintf(str,
"CAL_ACC%u_ID", i);
429 for (
int topic_instance = 0; topic_instance < MAG_COUNT_MAX
438 int topic_device_id = report.device_id;
439 bool is_external = report.is_external;
445 for (
unsigned driver_index = 0; driver_index <
MAG_COUNT_MAX; ++driver_index) {
449 DevMgr::getHandle(str, h);
456 int driver_device_id = h.ioctl(DEVIOCGDEVICEID, 0);
458 if (driver_device_id == topic_device_id) {
462 DevMgr::releaseHandle(h);
466 bool config_ok =
false;
473 (void)sprintf(str,
"CAL_MAG%u_ID", i);
477 (void)sprintf(str,
"CAL_MAG%u_EN", i);
478 int32_t device_enabled = 1;
487 _mag.
enabled[topic_instance] = (device_enabled == 1);
495 (void)sprintf(str,
"CAL_MAG%u_XOFF", i);
499 (void)sprintf(str,
"CAL_MAG%u_YOFF", i);
503 (void)sprintf(str,
"CAL_MAG%u_ZOFF", i);
507 (void)sprintf(str,
"CAL_MAG%u_XSCALE", i);
511 (void)sprintf(str,
"CAL_MAG%u_YSCALE", i);
515 (void)sprintf(str,
"CAL_MAG%u_ZSCALE", i);
519 (void)sprintf(str,
"CAL_MAG%u_ROT", i);
586 if (ret != PX4_OK || accel_report.
timestamp == 0) {
596 int32_t priority = 0;
626 accel_data =
Vector3f(accel_report.
x, accel_report.
y, accel_report.
z);
640 offsets[uorb_index], scales[uorb_index]) == 2) {
662 if (best_index >= 0) {
693 if (ret != PX4_OK || gyro_report.
timestamp == 0) {
703 int32_t priority = 0;
733 gyro_rate =
Vector3f(gyro_report.
x, gyro_report.
y, gyro_report.
z);
747 offsets[uorb_index], scales[uorb_index]) == 2) {
769 if (best_index >= 0) {
798 if (ret != PX4_OK || mag_report.timestamp == 0) {
808 int32_t priority = 0;
825 Vector3f vect(mag_report.x, mag_report.y, mag_report.z);
841 if (best_index >= 0) {
854 bool got_update =
false;
867 if (ret != PX4_OK || baro_report.
timestamp == 0) {
872 float corrected_pressure = 100.0f * baro_report.
pressure;
876 offsets[uorb_index], scales[uorb_index]) == 2) {
882 int32_t priority = 0;
905 if (best_index >= 0) {
922 static constexpr
float a = -6.5f / 1000.0f;
945 static constexpr
float pressure_to_density = 1.0f / (CONSTANTS_AIR_GAS_CONST * (20.0f -
960 if (failover_index != -1) {
962 PX4_INFO(
"%s sensor switch from #%i", sensor_name, failover_index);
966 if (failover_index != -1) {
977 sensor.
priority[failover_index] = 1;
979 PX4_ERR(
"Sensor %s #%i failed. Reconfiguring sensor priorities.", sensor_name, failover_index);
984 if (sensor.
priority[i] > 1) { ctr_valid++; }
986 PX4_WARN(
"Remaining sensors after failover event %u: %s #%u priority: %u", failover_index, sensor_name, i,
991 if (ctr_valid == 0) {
995 }
else if (ctr_valid == 1) {
997 if (type == subsystem_info_s::SUBSYSTEM_TYPE_GYRO) {
_info.
subsystem_type = subsystem_info_s::SUBSYSTEM_TYPE_GYRO2; }
999 if (type == subsystem_info_s::SUBSYSTEM_TYPE_ACC) {
_info.
subsystem_type = subsystem_info_s::SUBSYSTEM_TYPE_ACC2; }
1001 if (type == subsystem_info_s::SUBSYSTEM_TYPE_MAG) {
_info.
subsystem_type = subsystem_info_s::SUBSYSTEM_TYPE_MAG2; }
1022 uint8_t sensor_count_max)
1024 int max_sensor_index = -1;
1026 for (
unsigned i = 0; i < sensor_count_max; i++) {
1031 max_sensor_index = i;
1039 PX4_ERR(
"failed to add validator for sensor %s %i", meta->
o_name, i);
1053 PX4_INFO(
"gyro status:");
1055 PX4_INFO(
"accel status:");
1057 PX4_INFO(
"mag status:");
1059 PX4_INFO(
"baro status:");
1068 #if defined(__PX4_NUTTX) 1082 #if defined(__PX4_NUTTX) 1096 #if defined(__PX4_NUTTX) 1103 return !h.ioctl(
MAGIOCSSCALE, (
long unsigned int)mcal);
1157 float accel_diff_sum_max_sq = 0.0f;
1158 unsigned check_index = 0;
1166 float accel_diff_sum_sq = 0.0f;
1169 for (
unsigned axis_index = 0; axis_index < 3; axis_index++) {
1178 if (accel_diff_sum_sq > accel_diff_sum_max_sq) {
1179 accel_diff_sum_max_sq = accel_diff_sum_sq;
1188 if (check_index >= 2) {
1195 if (check_index < 1) {
1206 float gyro_diff_sum_max_sq = 0.0f;
1207 unsigned check_index = 0;
1215 float gyro_diff_sum_sq = 0.0f;
1218 for (
unsigned axis_index = 0; axis_index < 3; axis_index++) {
1227 if (gyro_diff_sum_sq > gyro_diff_sum_max_sq) {
1228 gyro_diff_sum_max_sq = gyro_diff_sum_sq;
1237 if (check_index >= 2) {
1244 if (check_index < 1) {
1256 float mag_angle_diff_max = 0.0f;
1257 unsigned check_index = 0;
1265 float angle_error =
AxisAnglef(
Quatf(current_mag, primary_mag)).angle();
1278 if (check_index >= 2) {
uint32_t _baro_device_id[SENSOR_COUNT_MAX]
baro driver device id for each uorb instance
sensor_selection_s _selection
struct containing the sensor selection to be published to the uORB
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
static constexpr uint32_t ERROR_FLAG_NO_ERROR
Data validator error states.
static constexpr float CONSTANTS_AIR_GAS_CONST
bool applyMagCalibration(DriverFramework::DevHandle &h, const struct mag_calibration_s *mcal, const int device_id)
Apply a mag calibration.
static constexpr float CONSTANTS_ABSOLUTE_NULL_CELSIUS
vehicle_magnetometer_s _last_magnetometer[SENSOR_COUNT_MAX]
latest sensor data from all sensors instances
void magPoll(vehicle_magnetometer_s &magnetometer)
Poll the magnetometer for updated data.
VotedSensorsUpdate(const Parameters ¶meters, bool hil_enabled)
void sensorsPoll(sensor_combined_s &raw, vehicle_air_data_s &airdata, vehicle_magnetometer_s &magnetometer)
read new sensor data
float mag_inconsistency_angle
constexpr uint8_t GYRO_COUNT_MAX
int set_sensor_id_accel(uint32_t device_id, int topic_instance)
void put(unsigned index, uint64_t timestamp, const float val[3], uint64_t error_count, int priority)
Put an item into the validator group.
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
gyro scaling factors; Vout = (Vin * Vscale) + Voffset
Definition of geo / math functions to perform geodesic calculations.
uint8_t selected_accel_instance
void set_timeout(uint32_t timeout_interval_us)
Set the timeout value for the whole group.
uORB::Publication< sensor_correction_s > _sensor_correction_pub
handle to the sensor correction uORB topic
void setRelativeTimestamps(sensor_combined_s &raw)
set the relative timestamps of each sensor timestamp, based on the last sensorsPoll, so that the data can be published.
__EXPORT int param_set_no_notification(param_t param, const void *val)
Set the value of a parameter, but do not notify the system about the change.
sensor_correction_s _corrections
struct containing the sensor corrections to be published to the uORB
void baroPoll(vehicle_air_data_s &airdata)
Poll the barometer for updated data.
int orb_priority(int handle, int32_t *priority)
vehicle_air_data_s _last_airdata[SENSOR_COUNT_MAX]
latest sensor data from all sensors instances
__EXPORT int param_set(param_t param, const void *val)
Set the value of a parameter.
orb_advert_t _mavlink_log_pub
bool publish(const T &data)
Publish the struct.
mag scaling factors; Vout = (Vin * Vscale) + Voffset
static constexpr uint32_t ERROR_FLAG_TIMEOUT
int failover_index()
Get the index of the failed sensor in the group.
float accelerometer_m_s2[3]
void initializeSensors()
This tries to find new sensor instances.
static const char * sensor_name
int orb_exists(const struct orb_metadata *meta, int instance)
void print()
Print the validator value.
uint32_t failover_state()
Get the error state of the failed sensor in the group.
static int32_t device_id[max_accel_sens]
int init(sensor_combined_s &raw)
initialize subscriptions etc.
static constexpr float CONSTANTS_ONE_G
void calcMagInconsistency(sensor_preflight_s &preflt)
Calculates the magnitude in Gauss of the largest difference between the primary and any other magneto...
accel scaling factors; Vout = Vscale * (Vin + Voffset)
static constexpr uint32_t ERROR_FLAG_STALE_DATA
uint32_t _gyro_device_id[SENSOR_COUNT_MAX]
gyro driver device id for each uorb instance
#define CAL_ERROR_APPLY_CAL_MSG
const bool _hil_enabled
is hardware-in-the-loop mode enabled?
float * get_best(uint64_t timestamp, int *index)
Get the best data triplet of the group.
#define ACCEL_BASE_DEVICE_PATH
sensor_combined_s _last_sensor_data[SENSOR_COUNT_MAX]
latest sensor data from all sensors instances
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
static constexpr uint32_t ERROR_FLAG_HIGH_ERRCOUNT
float gyro_inconsistency_rad_s
bool publish(const T &data)
Publish the struct.
#define MAGIOCSSCALE
set the mag scaling constants to the structure pointed to by (arg)
constexpr uint8_t ACCEL_COUNT_MAX
constexpr uint8_t MAG_COUNT_MAX
#define GYRO_BASE_DEVICE_PATH
#define MAG_BASE_DEVICE_PATH
int parameters_update(bool hil_enabled=false)
(re)load the parameters.
bool _selection_changed
true when a sensor selection has changed and not been published
Rotation
Enum for board and external compass rotations.
void set_equal_value_threshold(uint32_t threshold)
Set the equal count threshold for the whole group.
int orb_unsubscribe(int handle)
DataValidator * add_new_validator()
Create a new Validator (with index equal to the number of currently existing validators) ...
uint8_t priority[SENSOR_COUNT_MAX]
sensor priority
float _gyro_diff[3][2]
filtered gyro differences between IMU uinits (rad/s)
int subscription[SENSOR_COUNT_MAX]
raw sensor data subscription
uint32_t _accel_device_id[SENSOR_COUNT_MAX]
accel driver device id for each uorb instance
unsigned int last_failover_count
bool _corrections_changed
uint32_t gyro_integral_dt
uint64_t _last_accel_timestamp[ACCEL_COUNT_MAX]
latest full timestamp
void initSensorClass(const orb_metadata *meta, SensorData &sensor_data, uint8_t sensor_count_max)
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
uint8_t selected_baro_instance
Vector3< float > Vector3f
#define ACCELIOCSSCALE
set the accel scaling constants to the structure pointed to by (arg)
static constexpr uint32_t ERROR_FLAG_NO_DATA
struct uart_esc::@18 _parameters
int set_sensor_id_gyro(uint32_t device_id, int topic_instance)
supply information which device_id matches a specific uORB topic_instance (needed if a system has mul...
static constexpr uint32_t ERROR_FLAG_HIGH_ERRDENSITY
unsigned failover_count() const
Get the number of failover events.
constexpr _Tp max(_Tp a, _Tp b)
void calcAccelInconsistency(sensor_preflight_s &preflt)
Calculates the magnitude in m/s/s of the largest difference between the primary and any other accel s...
float _mag_angle_diff[2]
filtered mag angle differences between sensor instances (Ga)
Quaternion< float > Quatf
TemperatureCompensation _temperature_compensation
sensor thermal compensation
matrix::Dcmf _mag_rotation[MAG_COUNT_MAX]
rotation matrix for the orientation that the external mag0 is mounted
void print_status()
output current configuration status to console
int orb_check(int handle, bool *updated)
int orb_subscribe_multi(const struct orb_metadata *meta, unsigned instance)
bool applyAccelCalibration(DriverFramework::DevHandle &h, const struct accel_calibration_s *acal, const int device_id)
Apply a accel calibration.
uint32_t _mag_device_id[SENSOR_COUNT_MAX]
mag driver device id for each uorb instance
void parametersUpdate()
call this whenever parameters got updated.
uint8_t selected_gyro_instance
#define mavlink_log_emergency(_pub, _text,...)
Send a mavlink emergency message and print to console.
__EXPORT matrix::Dcmf get_rot_matrix(enum Rotation rot)
Get the rotation matrix.
#define GYROIOCSSCALE
set the gyro scaling constants to (arg)
int apply_corrections_baro(int topic_instance, float &sensor_data, float temperature, float *offsets, float *scales)
AxisAngle< float > AxisAnglef
matrix::Dcmf _board_rotation
rotation matrix for the orientation that the board is mounted
uORB::Publication< sensor_selection_s > _sensor_selection_pub
handle to the sensor selection uORB topic
void accelPoll(sensor_combined_s &raw)
Poll the accelerometer for updated data.
uORB::PublicationQueued< subsystem_info_s > _info_pub
int apply_corrections_accel(int topic_instance, matrix::Vector3f &sensor_data, float temperature, float *offsets, float *scales)
bool enabled[SENSOR_COUNT_MAX]
int apply_corrections_gyro(int topic_instance, matrix::Vector3f &sensor_data, float temperature, float *offsets, float *scales)
Apply Thermal corrections to gyro (& other) sensor data.
int32_t accelerometer_timestamp_relative
int set_sensor_id_baro(uint32_t device_id, int topic_instance)
subsystem_info_s _info
subsystem info publication
#define MAG_ROT_VAL_INTERNAL
void deinit()
deinitialize the object (we cannot use the destructor because it is called on the wrong thread) ...
constexpr uint8_t BARO_COUNT_MAX
void checkFailover()
check if a failover event occured.
void gyroPoll(sensor_combined_s &raw)
Poll the gyro for updated data.
float _accel_diff[3][2]
filtered accel differences between IMU units (m/s/s)
uint32_t accelerometer_integral_dt
void calcGyroInconsistency(sensor_preflight_s &preflt)
Calculates the magnitude in rad/s of the largest difference between the primary and any other gyro se...
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
const Parameters & _parameters
uint8_t last_best_vote
index of the latest best vote
float accel_inconsistency_m_s_s
bool applyGyroCalibration(DriverFramework::DevHandle &h, const struct gyro_calibration_s *gcal, const int device_id)
Apply a gyro calibration.