forked from Archive/PX4-Autopilot
Merge master into cmake-2
This commit is contained in:
commit
fefdcd3fa9
|
@ -365,11 +365,6 @@ then
|
||||||
then
|
then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
|
||||||
# UAVCAN
|
|
||||||
#
|
|
||||||
sh /etc/init.d/rc.uavcan
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Sensors System (start before Commander so Preflight checks are properly run)
|
# Sensors System (start before Commander so Preflight checks are properly run)
|
||||||
#
|
#
|
||||||
|
@ -576,6 +571,11 @@ then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# UAVCAN
|
||||||
|
#
|
||||||
|
sh /etc/init.d/rc.uavcan
|
||||||
|
|
||||||
#
|
#
|
||||||
# Logging
|
# Logging
|
||||||
#
|
#
|
||||||
|
|
|
@ -53,5 +53,6 @@ mavlink stream -r 80 -s ATTITUDE -u 14556
|
||||||
mavlink stream -r 80 -s ATTITUDE_TARGET -u 14556
|
mavlink stream -r 80 -s ATTITUDE_TARGET -u 14556
|
||||||
mavlink stream -r 20 -s RC_CHANNELS -u 14556
|
mavlink stream -r 20 -s RC_CHANNELS -u 14556
|
||||||
mavlink stream -r 250 -s HIGHRES_IMU -u 14556
|
mavlink stream -r 250 -s HIGHRES_IMU -u 14556
|
||||||
|
mavlink stream -r 10 -s OPTICAL_FLOW_RAD -u 14556
|
||||||
mavlink boot_complete
|
mavlink boot_complete
|
||||||
sdlog2 start -r 100 -e -t -a
|
sdlog2 start -r 100 -e -t -a
|
||||||
|
|
|
@ -44,9 +44,10 @@
|
||||||
|
|
||||||
DataValidator::DataValidator(DataValidator *prev_sibling) :
|
DataValidator::DataValidator(DataValidator *prev_sibling) :
|
||||||
_time_last(0),
|
_time_last(0),
|
||||||
_timeout_interval(70000),
|
_timeout_interval(20000),
|
||||||
_event_count(0),
|
_event_count(0),
|
||||||
_error_count(0),
|
_error_count(0),
|
||||||
|
_error_density(0),
|
||||||
_priority(0),
|
_priority(0),
|
||||||
_mean{0.0f},
|
_mean{0.0f},
|
||||||
_lp{0.0f},
|
_lp{0.0f},
|
||||||
|
@ -68,6 +69,13 @@ void
|
||||||
DataValidator::put(uint64_t timestamp, float val[3], uint64_t error_count_in, int priority_in)
|
DataValidator::put(uint64_t timestamp, float val[3], uint64_t error_count_in, int priority_in)
|
||||||
{
|
{
|
||||||
_event_count++;
|
_event_count++;
|
||||||
|
|
||||||
|
if (error_count_in > _error_count) {
|
||||||
|
_error_density += (error_count_in - _error_count);
|
||||||
|
} else if (_error_density > 0) {
|
||||||
|
_error_density--;
|
||||||
|
}
|
||||||
|
|
||||||
_error_count = error_count_in;
|
_error_count = error_count_in;
|
||||||
_priority = priority_in;
|
_priority = priority_in;
|
||||||
|
|
||||||
|
@ -123,7 +131,13 @@ DataValidator::confidence(uint64_t timestamp)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1.0f;
|
/* cap error density counter at window size */
|
||||||
|
if (_error_density > ERROR_DENSITY_WINDOW) {
|
||||||
|
_error_density = ERROR_DENSITY_WINDOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return local error density for last N measurements */
|
||||||
|
return 1.0f - (_error_density / ERROR_DENSITY_WINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -136,12 +150,13 @@ void
|
||||||
DataValidator::print()
|
DataValidator::print()
|
||||||
{
|
{
|
||||||
if (_time_last == 0) {
|
if (_time_last == 0) {
|
||||||
ECL_INFO("\tno data\n");
|
ECL_INFO("\tno data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < _dimensions; i++) {
|
for (unsigned i = 0; i < _dimensions; i++) {
|
||||||
ECL_INFO("\tval: %8.4f, lp: %8.4f mean dev: %8.4f RMS: %8.4f\n",
|
ECL_INFO("\tval: %8.4f, lp: %8.4f mean dev: %8.4f RMS: %8.4f conf: %8.4f",
|
||||||
(double) _value[i], (double)_lp[i], (double)_mean[i], (double)_rms[i]);
|
(double) _value[i], (double)_lp[i], (double)_mean[i],
|
||||||
|
(double)_rms[i], (double)confidence(hrt_absolute_time()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,12 @@ public:
|
||||||
*/
|
*/
|
||||||
float* value() { return _value; }
|
float* value() { return _value; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the used status of this validator
|
||||||
|
* @return true if this validator ever saw data
|
||||||
|
*/
|
||||||
|
bool used() { return (_time_last > 0); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the priority of this validator
|
* Get the priority of this validator
|
||||||
* @return the stored priority
|
* @return the stored priority
|
||||||
|
@ -112,6 +118,7 @@ private:
|
||||||
uint64_t _timeout_interval; /**< interval in which the datastream times out in us */
|
uint64_t _timeout_interval; /**< interval in which the datastream times out in us */
|
||||||
uint64_t _event_count; /**< total data counter */
|
uint64_t _event_count; /**< total data counter */
|
||||||
uint64_t _error_count; /**< error count */
|
uint64_t _error_count; /**< error count */
|
||||||
|
int _error_density; /**< ratio between successful reads and errors */
|
||||||
int _priority; /**< sensor nominal priority */
|
int _priority; /**< sensor nominal priority */
|
||||||
float _mean[_dimensions]; /**< mean of value */
|
float _mean[_dimensions]; /**< mean of value */
|
||||||
float _lp[3]; /**< low pass value */
|
float _lp[3]; /**< low pass value */
|
||||||
|
@ -120,7 +127,8 @@ private:
|
||||||
float _value[3]; /**< last value */
|
float _value[3]; /**< last value */
|
||||||
float _value_equal_count; /**< equal values in a row */
|
float _value_equal_count; /**< equal values in a row */
|
||||||
DataValidator *_sibling; /**< sibling in the group */
|
DataValidator *_sibling; /**< sibling in the group */
|
||||||
const unsigned NORETURN_ERRCOUNT = 100; /**< if the error count reaches this value, return sensor as invalid */
|
const unsigned NORETURN_ERRCOUNT = 10000; /**< if the error count reaches this value, return sensor as invalid */
|
||||||
|
const float ERROR_DENSITY_WINDOW = 100.0f; /**< window in measurement counts for errors */
|
||||||
const unsigned VALUE_EQUAL_COUNT_MAX = 100; /**< if the sensor value is the same (accumulated also between axes) this many times, flag it */
|
const unsigned VALUE_EQUAL_COUNT_MAX = 100; /**< if the sensor value is the same (accumulated also between axes) this many times, flag it */
|
||||||
|
|
||||||
/* we don't want this class to be copied */
|
/* we don't want this class to be copied */
|
||||||
|
|
|
@ -97,24 +97,35 @@ DataValidatorGroup::get_best(uint64_t timestamp, int *index)
|
||||||
|
|
||||||
// XXX This should eventually also include voting
|
// XXX This should eventually also include voting
|
||||||
int pre_check_best = _curr_best;
|
int pre_check_best = _curr_best;
|
||||||
|
float pre_check_confidence = 1.0f;
|
||||||
|
int pre_check_prio = -1;
|
||||||
float max_confidence = -1.0f;
|
float max_confidence = -1.0f;
|
||||||
int max_priority = -1000;
|
int max_priority = -1000;
|
||||||
int max_index = -1;
|
int max_index = -1;
|
||||||
uint64_t min_error_count = 30000;
|
|
||||||
DataValidator *best = nullptr;
|
DataValidator *best = nullptr;
|
||||||
|
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
|
|
||||||
while (next != nullptr) {
|
while (next != nullptr) {
|
||||||
float confidence = next->confidence(timestamp);
|
float confidence = next->confidence(timestamp);
|
||||||
if (confidence > max_confidence ||
|
|
||||||
(fabsf(confidence - max_confidence) < 0.01f &&
|
if (i == pre_check_best) {
|
||||||
((next->error_count() < min_error_count) &&
|
pre_check_prio = next->priority();
|
||||||
(next->priority() >= max_priority)))) {
|
pre_check_confidence = confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switch if:
|
||||||
|
* 1) the confidence is higher and priority is equal or higher
|
||||||
|
* 2) the confidence is no less than 1% different and the priority is higher
|
||||||
|
*/
|
||||||
|
if (((max_confidence < MIN_REGULAR_CONFIDENCE) && (confidence >= MIN_REGULAR_CONFIDENCE)) ||
|
||||||
|
(confidence > max_confidence && (next->priority() >= max_priority)) ||
|
||||||
|
(fabsf(confidence - max_confidence) < 0.01f && (next->priority() > max_priority))
|
||||||
|
) {
|
||||||
max_index = i;
|
max_index = i;
|
||||||
max_confidence = confidence;
|
max_confidence = confidence;
|
||||||
max_priority = next->priority();
|
max_priority = next->priority();
|
||||||
min_error_count = next->error_count();
|
|
||||||
best = next;
|
best = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,17 +136,29 @@ DataValidatorGroup::get_best(uint64_t timestamp, int *index)
|
||||||
/* the current best sensor is not matching the previous best sensor */
|
/* the current best sensor is not matching the previous best sensor */
|
||||||
if (max_index != _curr_best) {
|
if (max_index != _curr_best) {
|
||||||
|
|
||||||
|
bool true_failsafe = true;
|
||||||
|
|
||||||
|
/* check wether the switch was a failsafe or preferring a higher priority sensor */
|
||||||
|
if (pre_check_prio != -1 && pre_check_prio < max_priority &&
|
||||||
|
fabsf(pre_check_confidence - max_confidence) < 0.1f) {
|
||||||
|
/* this is not a failover */
|
||||||
|
true_failsafe = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* if we're no initialized, initialize the bookkeeping but do not count a failsafe */
|
/* if we're no initialized, initialize the bookkeeping but do not count a failsafe */
|
||||||
if (_curr_best < 0) {
|
if (_curr_best < 0) {
|
||||||
_prev_best = max_index;
|
_prev_best = max_index;
|
||||||
} else {
|
} else {
|
||||||
/* we were initialized before, this is a real failsafe */
|
/* we were initialized before, this is a real failsafe */
|
||||||
_prev_best = pre_check_best;
|
_prev_best = pre_check_best;
|
||||||
_toggle_count++;
|
|
||||||
|
|
||||||
/* if this is the first time, log when we failed */
|
if (true_failsafe) {
|
||||||
if (_first_failover_time == 0) {
|
_toggle_count++;
|
||||||
_first_failover_time = timestamp;
|
|
||||||
|
/* if this is the first time, log when we failed */
|
||||||
|
if (_first_failover_time == 0) {
|
||||||
|
_first_failover_time = timestamp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,8 +208,10 @@ DataValidatorGroup::print()
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
|
|
||||||
while (next != nullptr) {
|
while (next != nullptr) {
|
||||||
ECL_INFO("sensor #%u:\n", i);
|
if (next->used()) {
|
||||||
next->print();
|
ECL_INFO("sensor #%u, prio: %d", i, next->priority());
|
||||||
|
next->print();
|
||||||
|
}
|
||||||
next = next->sibling();
|
next = next->sibling();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ private:
|
||||||
int _prev_best; /**< the previous best index */
|
int _prev_best; /**< the previous best index */
|
||||||
uint64_t _first_failover_time; /**< timestamp where the first failover occured or zero if none occured */
|
uint64_t _first_failover_time; /**< timestamp where the first failover occured or zero if none occured */
|
||||||
unsigned _toggle_count; /**< number of back and forth switches between two sensors */
|
unsigned _toggle_count; /**< number of back and forth switches between two sensors */
|
||||||
|
static constexpr float MIN_REGULAR_CONFIDENCE = 0.9f;
|
||||||
|
|
||||||
/* we don't want this class to be copied */
|
/* we don't want this class to be copied */
|
||||||
DataValidatorGroup(const DataValidatorGroup&);
|
DataValidatorGroup(const DataValidatorGroup&);
|
||||||
|
|
|
@ -116,4 +116,4 @@ PARAM_DEFINE_FLOAT(ATT_BIAS_MAX, 0.05f);
|
||||||
* @min 0.001
|
* @min 0.001
|
||||||
* @max 100
|
* @max 100
|
||||||
*/
|
*/
|
||||||
PARAM_DEFINE_FLOAT(ATT_VIBE_THRESH, 0.1f);
|
PARAM_DEFINE_FLOAT(ATT_VIBE_THRESH, 0.2f);
|
||||||
|
|
|
@ -1666,6 +1666,7 @@ Mavlink::task_main(int argc, char *argv[])
|
||||||
configure_stream("GPS_RAW_INT", 1.0f);
|
configure_stream("GPS_RAW_INT", 1.0f);
|
||||||
configure_stream("GLOBAL_POSITION_INT", 3.0f);
|
configure_stream("GLOBAL_POSITION_INT", 3.0f);
|
||||||
configure_stream("LOCAL_POSITION_NED", 3.0f);
|
configure_stream("LOCAL_POSITION_NED", 3.0f);
|
||||||
|
configure_stream("NAMED_VALUE_FLOAT", 2.0f);
|
||||||
configure_stream("RC_CHANNELS", 1.0f);
|
configure_stream("RC_CHANNELS", 1.0f);
|
||||||
configure_stream("SERVO_OUTPUT_RAW_0", 1.0f);
|
configure_stream("SERVO_OUTPUT_RAW_0", 1.0f);
|
||||||
configure_stream("POSITION_TARGET_GLOBAL_INT", 3.0f);
|
configure_stream("POSITION_TARGET_GLOBAL_INT", 3.0f);
|
||||||
|
@ -1682,6 +1683,7 @@ Mavlink::task_main(int argc, char *argv[])
|
||||||
configure_stream("GPS_RAW_INT", 5.0f);
|
configure_stream("GPS_RAW_INT", 5.0f);
|
||||||
configure_stream("GLOBAL_POSITION_INT", 50.0f);
|
configure_stream("GLOBAL_POSITION_INT", 50.0f);
|
||||||
configure_stream("LOCAL_POSITION_NED", 30.0f);
|
configure_stream("LOCAL_POSITION_NED", 30.0f);
|
||||||
|
configure_stream("NAMED_VALUE_FLOAT", 10.0f);
|
||||||
configure_stream("CAMERA_CAPTURE", 2.0f);
|
configure_stream("CAMERA_CAPTURE", 2.0f);
|
||||||
configure_stream("HOME_POSITION", 0.5f);
|
configure_stream("HOME_POSITION", 0.5f);
|
||||||
configure_stream("ATTITUDE_TARGET", 10.0f);
|
configure_stream("ATTITUDE_TARGET", 10.0f);
|
||||||
|
@ -1723,7 +1725,7 @@ Mavlink::task_main(int argc, char *argv[])
|
||||||
configure_stream("ATTITUDE_TARGET", 8.0f);
|
configure_stream("ATTITUDE_TARGET", 8.0f);
|
||||||
configure_stream("PARAM_VALUE", 300.0f);
|
configure_stream("PARAM_VALUE", 300.0f);
|
||||||
configure_stream("MISSION_ITEM", 50.0f);
|
configure_stream("MISSION_ITEM", 50.0f);
|
||||||
configure_stream("NAMED_VALUE_FLOAT", 10.0f);
|
configure_stream("NAMED_VALUE_FLOAT", 50.0f);
|
||||||
configure_stream("OPTICAL_FLOW_RAD", 10.0f);
|
configure_stream("OPTICAL_FLOW_RAD", 10.0f);
|
||||||
configure_stream("DISTANCE_SENSOR", 10.0f);
|
configure_stream("DISTANCE_SENSOR", 10.0f);
|
||||||
configure_stream("VFR_HUD", 20.0f);
|
configure_stream("VFR_HUD", 20.0f);
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include <drivers/drv_hrt.h>
|
#include <drivers/drv_hrt.h>
|
||||||
#include <drivers/drv_rc_input.h>
|
#include <drivers/drv_rc_input.h>
|
||||||
#include <uORB/uORB.h>
|
#include <uORB/uORB.h>
|
||||||
|
#include <uORB/topics/optical_flow.h>
|
||||||
#include <v1.0/mavlink_types.h>
|
#include <v1.0/mavlink_types.h>
|
||||||
#include <v1.0/common/mavlink.h>
|
#include <v1.0/common/mavlink.h>
|
||||||
namespace simulator
|
namespace simulator
|
||||||
|
@ -259,11 +260,13 @@ private:
|
||||||
orb_advert_t _baro_pub;
|
orb_advert_t _baro_pub;
|
||||||
orb_advert_t _gyro_pub;
|
orb_advert_t _gyro_pub;
|
||||||
orb_advert_t _mag_pub;
|
orb_advert_t _mag_pub;
|
||||||
|
orb_advert_t _flow_pub;
|
||||||
|
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
|
|
||||||
// class methods
|
// class methods
|
||||||
int publish_sensor_topics(mavlink_hil_sensor_t *imu);
|
int publish_sensor_topics(mavlink_hil_sensor_t *imu);
|
||||||
|
int publish_flow_topic(mavlink_hil_optical_flow_t *flow);
|
||||||
|
|
||||||
#ifndef __PX4_QURT
|
#ifndef __PX4_QURT
|
||||||
// uORB publisher handlers
|
// uORB publisher handlers
|
||||||
|
|
|
@ -245,6 +245,12 @@ void Simulator::handle_message(mavlink_message_t *msg, bool publish)
|
||||||
update_sensors(&imu);
|
update_sensors(&imu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MAVLINK_MSG_ID_HIL_OPTICAL_FLOW:
|
||||||
|
mavlink_hil_optical_flow_t flow;
|
||||||
|
mavlink_msg_hil_optical_flow_decode(msg, &flow);
|
||||||
|
publish_flow_topic(&flow);
|
||||||
|
break;
|
||||||
|
|
||||||
case MAVLINK_MSG_ID_HIL_GPS:
|
case MAVLINK_MSG_ID_HIL_GPS:
|
||||||
mavlink_hil_gps_t gps_sim;
|
mavlink_hil_gps_t gps_sim;
|
||||||
mavlink_msg_hil_gps_decode(msg, &gps_sim);
|
mavlink_msg_hil_gps_decode(msg, &gps_sim);
|
||||||
|
@ -762,3 +768,38 @@ int Simulator::publish_sensor_topics(mavlink_hil_sensor_t *imu)
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Simulator::publish_flow_topic(mavlink_hil_optical_flow_t* flow_mavlink)
|
||||||
|
{
|
||||||
|
uint64_t timestamp = hrt_absolute_time();
|
||||||
|
|
||||||
|
/* flow */
|
||||||
|
{
|
||||||
|
struct optical_flow_s flow;
|
||||||
|
memset(&flow, 0, sizeof(flow));
|
||||||
|
|
||||||
|
flow.sensor_id = flow_mavlink->sensor_id;
|
||||||
|
flow.timestamp = timestamp;
|
||||||
|
flow.time_since_last_sonar_update = 0;
|
||||||
|
flow.frame_count_since_last_readout = 0; // ?
|
||||||
|
flow.integration_timespan = flow_mavlink->integration_time_us;
|
||||||
|
|
||||||
|
flow.ground_distance_m = flow_mavlink->distance;
|
||||||
|
flow.gyro_temperature = flow_mavlink->temperature;
|
||||||
|
flow.gyro_x_rate_integral = flow_mavlink->integrated_xgyro;
|
||||||
|
flow.gyro_y_rate_integral = flow_mavlink->integrated_ygyro;
|
||||||
|
flow.gyro_z_rate_integral = flow_mavlink->integrated_zgyro;
|
||||||
|
flow.pixel_flow_x_integral = flow_mavlink->integrated_x;
|
||||||
|
flow.pixel_flow_x_integral = flow_mavlink->integrated_y;
|
||||||
|
flow.quality = flow_mavlink->quality;
|
||||||
|
|
||||||
|
if (_flow_pub == nullptr) {
|
||||||
|
_flow_pub = orb_advertise(ORB_ID(optical_flow), &flow);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
orb_publish(ORB_ID(optical_flow), _flow_pub, &flow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue