AP_RangeFinder: remove primary, add orientation

This commit is contained in:
Randy Mackay 2017-02-09 19:26:57 +09:00
parent 49f4afc2a1
commit e7dd21a0bb
2 changed files with 162 additions and 47 deletions

View File

@ -152,6 +152,13 @@ const AP_Param::GroupInfo RangeFinder::var_info[] = {
// @User: Advanced // @User: Advanced
AP_GROUPINFO("_POS", 49, RangeFinder, _pos_offset[0], 0.0f), AP_GROUPINFO("_POS", 49, RangeFinder, _pos_offset[0], 0.0f),
// @Param: _ORIENT
// @DisplayName: Rangefinder orientation
// @Description: Orientation of rangefinder
// @Values: 0:Forward, 1:Forward-Right, 2:Right, 3:Back-Right, 4:Back, 5:Back-Left, 6:Left, 7:Forward-Left, 24:Up, 25:Down
// @User: Advanced
AP_GROUPINFO("_ORIENT", 53, RangeFinder, _orientation[0], ROTATION_PITCH_270),
#if RANGEFINDER_MAX_INSTANCES > 1 #if RANGEFINDER_MAX_INSTANCES > 1
// @Param: 2_TYPE // @Param: 2_TYPE
// @DisplayName: Second Rangefinder type // @DisplayName: Second Rangefinder type
@ -264,6 +271,12 @@ const AP_Param::GroupInfo RangeFinder::var_info[] = {
// @User: Advanced // @User: Advanced
AP_GROUPINFO("2_POS", 50, RangeFinder, _pos_offset[1], 0.0f), AP_GROUPINFO("2_POS", 50, RangeFinder, _pos_offset[1], 0.0f),
// @Param: 2_ORIENT
// @DisplayName: Rangefinder 2 orientation
// @Description: Orientation of 2nd rangefinder
// @Values: 0:Forward, 1:Forward-Right, 2:Right, 3:Back-Right, 4:Back, 5:Back-Left, 6:Left, 7:Forward-Left, 24:Up, 25:Down
// @User: Advanced
AP_GROUPINFO("2_ORIENT", 54, RangeFinder, _orientation[1], ROTATION_PITCH_270),
#endif #endif
#if RANGEFINDER_MAX_INSTANCES > 2 #if RANGEFINDER_MAX_INSTANCES > 2
@ -379,6 +392,12 @@ const AP_Param::GroupInfo RangeFinder::var_info[] = {
// @User: Advanced // @User: Advanced
AP_GROUPINFO("3_POS", 51, RangeFinder, _pos_offset[2], 0.0f), AP_GROUPINFO("3_POS", 51, RangeFinder, _pos_offset[2], 0.0f),
// @Param: 3_ORIENT
// @DisplayName: Rangefinder 3 orientation
// @Description: Orientation of 3rd rangefinder
// @Values: 0:Forward, 1:Forward-Right, 2:Right, 3:Back-Right, 4:Back, 5:Back-Left, 6:Left, 7:Forward-Left, 24:Up, 25:Down
// @User: Advanced
AP_GROUPINFO("3_ORIENT", 55, RangeFinder, _orientation[2], ROTATION_PITCH_270),
#endif #endif
#if RANGEFINDER_MAX_INSTANCES > 3 #if RANGEFINDER_MAX_INSTANCES > 3
@ -493,19 +512,30 @@ const AP_Param::GroupInfo RangeFinder::var_info[] = {
// @Units: m // @Units: m
// @User: Advanced // @User: Advanced
AP_GROUPINFO("4_POS", 52, RangeFinder, _pos_offset[3], 0.0f), AP_GROUPINFO("4_POS", 52, RangeFinder, _pos_offset[3], 0.0f),
// @Param: 4_ORIENT
// @DisplayName: Rangefinder 4 orientation
// @Description: Orientation of 4th range finder
// @Values: 0:Forward, 1:Forward-Right, 2:Right, 3:Back-Right, 4:Back, 5:Back-Left, 6:Left, 7:Forward-Left, 24:Up, 25:Down
// @User: Advanced
AP_GROUPINFO("4_ORIENT", 56, RangeFinder, _orientation[3], ROTATION_PITCH_270),
#endif #endif
AP_GROUPEND AP_GROUPEND
}; };
RangeFinder::RangeFinder(AP_SerialManager &_serial_manager) : RangeFinder::RangeFinder(AP_SerialManager &_serial_manager, enum Rotation orientation_default) :
primary_instance(0),
num_instances(0), num_instances(0),
estimated_terrain_height(0), estimated_terrain_height(0),
serial_manager(_serial_manager) serial_manager(_serial_manager)
{ {
AP_Param::setup_object_defaults(this, var_info); AP_Param::setup_object_defaults(this, var_info);
// set orientation defaults
for (uint8_t i=0; i<RANGEFINDER_MAX_INSTANCES; i++) {
_orientation[i].set_default(orientation_default);
}
// init state and drivers // init state and drivers
memset(state,0,sizeof(state)); memset(state,0,sizeof(state));
memset(drivers,0,sizeof(drivers)); memset(drivers,0,sizeof(drivers));
@ -558,13 +588,6 @@ void RangeFinder::update(void)
update_pre_arm_check(i); update_pre_arm_check(i);
} }
} }
// work out primary instance - first sensor returning good data
for (int8_t i=num_instances-1; i>=0; i--) {
if (drivers[i] != nullptr && (state[i].status == RangeFinder_Good)) {
primary_instance = i;
}
}
} }
bool RangeFinder::_add_backend(AP_RangeFinder_Backend *backend) bool RangeFinder::_add_backend(AP_RangeFinder_Backend *backend)
@ -688,13 +711,87 @@ RangeFinder::RangeFinder_Status RangeFinder::status(uint8_t instance) const
return state[instance].status; return state[instance].status;
} }
void RangeFinder::handle_msg(mavlink_message_t *msg) { RangeFinder::RangeFinder_Status RangeFinder::status_orient(enum Rotation orientation) const
uint8_t i; {
for (i=0; i<num_instances; i++) { uint8_t i;
if ((drivers[i] != nullptr) && (_type[i] != RangeFinder_TYPE_NONE)) { if (find_instance(orientation, i)) {
return status(i);
}
return RangeFinder_NotConnected;
}
void RangeFinder::handle_msg(mavlink_message_t *msg)
{
uint8_t i;
for (i=0; i<num_instances; i++) {
if ((drivers[i] != nullptr) && (_type[i] != RangeFinder_TYPE_NONE)) {
drivers[i]->handle_msg(msg); drivers[i]->handle_msg(msg);
} }
} }
}
// return true if we have a range finder with the specified orientation
bool RangeFinder::has_orientation(enum Rotation orientation) const
{
uint8_t i;
return find_instance(orientation, i);
}
// find first range finder instance with the specified orientation
bool RangeFinder::find_instance(enum Rotation orientation, uint8_t &instance) const
{
for (uint8_t i=0; i<num_instances; i++) {
if (_orientation[i] == orientation) {
instance = i;
return true;
}
}
return false;
}
uint16_t RangeFinder::distance_cm_orient(enum Rotation orientation) const
{
uint8_t i;
if (find_instance(orientation, i)) {
return distance_cm(i);
}
return 0;
}
uint16_t RangeFinder::voltage_mv_orient(enum Rotation orientation) const
{
uint8_t i;
if (find_instance(orientation, i)) {
return voltage_mv(i);
}
return 0;
}
int16_t RangeFinder::max_distance_cm_orient(enum Rotation orientation) const
{
uint8_t i;
if (find_instance(orientation, i)) {
return max_distance_cm(i);
}
return 0;
}
int16_t RangeFinder::min_distance_cm_orient(enum Rotation orientation) const
{
uint8_t i;
if (find_instance(orientation, i)) {
return min_distance_cm(i);
}
return 0;
}
int16_t RangeFinder::ground_clearance_cm_orient(enum Rotation orientation) const
{
uint8_t i;
if (find_instance(orientation, i)) {
return ground_clearance_cm(i);
}
return 0;
} }
// true if sensor is returning data // true if sensor is returning data
@ -707,6 +804,24 @@ bool RangeFinder::has_data(uint8_t instance) const
return ((state[instance].status != RangeFinder_NotConnected) && (state[instance].status != RangeFinder_NoData)); return ((state[instance].status != RangeFinder_NotConnected) && (state[instance].status != RangeFinder_NoData));
} }
bool RangeFinder::has_data_orient(enum Rotation orientation) const
{
uint8_t i;
if (find_instance(orientation, i)) {
return has_data(i);
}
return false;
}
uint8_t RangeFinder::range_valid_count_orient(enum Rotation orientation) const
{
uint8_t i;
if (find_instance(orientation, i)) {
return range_valid_count(i);
}
return 0;
}
/* /*
returns true if pre-arm checks have passed for all range finders returns true if pre-arm checks have passed for all range finders
these checks involve the user lifting or rotating the vehicle so that sensor readings between these checks involve the user lifting or rotating the vehicle so that sensor readings between
@ -748,3 +863,12 @@ void RangeFinder::update_pre_arm_check(uint8_t instance)
state[instance].pre_arm_check = true; state[instance].pre_arm_check = true;
} }
} }
const Vector3f &RangeFinder::get_pos_offset_orient(enum Rotation orientation) const
{
uint8_t i=0;
if (find_instance(orientation, i)) {
return get_pos_offset(i);
}
return pos_offset_zero;
}

View File

@ -33,7 +33,7 @@ class RangeFinder
public: public:
friend class AP_RangeFinder_Backend; friend class AP_RangeFinder_Backend;
RangeFinder(AP_SerialManager &_serial_manager); RangeFinder(AP_SerialManager &_serial_manager, enum Rotation orientation_default);
// RangeFinder driver types // RangeFinder driver types
enum RangeFinder_Type { enum RangeFinder_Type {
@ -96,6 +96,7 @@ public:
AP_Int8 _address[RANGEFINDER_MAX_INSTANCES]; AP_Int8 _address[RANGEFINDER_MAX_INSTANCES];
AP_Int16 _powersave_range; AP_Int16 _powersave_range;
AP_Vector3f _pos_offset[RANGEFINDER_MAX_INSTANCES]; // position offset in body frame AP_Vector3f _pos_offset[RANGEFINDER_MAX_INSTANCES]; // position offset in body frame
AP_Int8 _orientation[RANGEFINDER_MAX_INSTANCES];
static const struct AP_Param::GroupInfo var_info[]; static const struct AP_Param::GroupInfo var_info[];
@ -116,63 +117,55 @@ public:
#define _RangeFinder_STATE(instance) state[instance] #define _RangeFinder_STATE(instance) state[instance]
uint8_t get_primary(void) const { // return true if we have a range finder with the specified orientation
return primary_instance; bool has_orientation(enum Rotation orientation) const;
// find first range finder instance with the specified orientation
bool find_instance(enum Rotation orientation, uint8_t &instance) const;
// get orientation of a given range finder
enum Rotation get_orientation(uint8_t instance) const {
return (instance<num_instances? (enum Rotation)_orientation[instance].get() : ROTATION_NONE);
} }
uint16_t distance_cm(uint8_t instance) const { uint16_t distance_cm(uint8_t instance) const {
return (instance<num_instances? _RangeFinder_STATE(instance).distance_cm : 0); return (instance<num_instances? _RangeFinder_STATE(instance).distance_cm : 0);
} }
uint16_t distance_cm() const { uint16_t distance_cm_orient(enum Rotation orientation) const;
return distance_cm(primary_instance);
}
uint16_t voltage_mv(uint8_t instance) const { uint16_t voltage_mv(uint8_t instance) const {
return _RangeFinder_STATE(instance).voltage_mv; return _RangeFinder_STATE(instance).voltage_mv;
} }
uint16_t voltage_mv() const { uint16_t voltage_mv_orient(enum Rotation orientation) const;
return voltage_mv(primary_instance);
}
int16_t max_distance_cm(uint8_t instance) const { int16_t max_distance_cm(uint8_t instance) const {
return _max_distance_cm[instance]; return _max_distance_cm[instance];
} }
int16_t max_distance_cm() const { int16_t max_distance_cm_orient(enum Rotation orientation) const;
return max_distance_cm(primary_instance);
}
int16_t min_distance_cm(uint8_t instance) const { int16_t min_distance_cm(uint8_t instance) const {
return _min_distance_cm[instance]; return _min_distance_cm[instance];
} }
int16_t min_distance_cm() const { int16_t min_distance_cm_orient(enum Rotation orientation) const;
return min_distance_cm(primary_instance);
}
int16_t ground_clearance_cm(uint8_t instance) const { int16_t ground_clearance_cm(uint8_t instance) const {
return _ground_clearance_cm[instance]; return _ground_clearance_cm[instance];
} }
int16_t ground_clearance_cm() const { int16_t ground_clearance_cm_orient(enum Rotation orientation) const;
return _ground_clearance_cm[primary_instance];
}
// query status // query status
RangeFinder_Status status(uint8_t instance) const; RangeFinder_Status status(uint8_t instance) const;
RangeFinder_Status status(void) const { RangeFinder_Status status_orient(enum Rotation orientation) const;
return status(primary_instance);
}
// true if sensor is returning data // true if sensor is returning data
bool has_data(uint8_t instance) const; bool has_data(uint8_t instance) const;
bool has_data() const { bool has_data_orient(enum Rotation orientation) const;
return has_data(primary_instance);
}
// returns count of consecutive good readings // returns count of consecutive good readings
uint8_t range_valid_count() const {
return range_valid_count(primary_instance);
}
uint8_t range_valid_count(uint8_t instance) const { uint8_t range_valid_count(uint8_t instance) const {
return _RangeFinder_STATE(instance).range_valid_count; return _RangeFinder_STATE(instance).range_valid_count;
} }
uint8_t range_valid_count_orient(enum Rotation orientation) const;
/* /*
set an externally estimated terrain height. Used to enable power set an externally estimated terrain height. Used to enable power
@ -193,17 +186,15 @@ public:
const Vector3f &get_pos_offset(uint8_t instance) const { const Vector3f &get_pos_offset(uint8_t instance) const {
return _pos_offset[instance]; return _pos_offset[instance];
} }
const Vector3f &get_pos_offset(void) const { const Vector3f &get_pos_offset_orient(enum Rotation orientation) const;
return _pos_offset[primary_instance];
}
private: private:
RangeFinder_State state[RANGEFINDER_MAX_INSTANCES]; RangeFinder_State state[RANGEFINDER_MAX_INSTANCES];
AP_RangeFinder_Backend *drivers[RANGEFINDER_MAX_INSTANCES]; AP_RangeFinder_Backend *drivers[RANGEFINDER_MAX_INSTANCES];
uint8_t primary_instance:3;
uint8_t num_instances:3; uint8_t num_instances:3;
float estimated_terrain_height; float estimated_terrain_height;
AP_SerialManager &serial_manager; AP_SerialManager &serial_manager;
Vector3f pos_offset_zero; // allows returning position offsets of zero for invalid requests
void detect_instance(uint8_t instance); void detect_instance(uint8_t instance);
void update_instance(uint8_t instance); void update_instance(uint8_t instance);