|
|
@ -130,9 +130,14 @@ void AP_Proximity::update() |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
drivers[i]->update(); |
|
|
|
drivers[i]->update(); |
|
|
|
drivers[i]->boundary_3D_checks(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// set boundary cutoff freq for low pass filter
|
|
|
|
|
|
|
|
boundary.set_filter_freq(get_filter_freq()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if any face has valid distance when it should not
|
|
|
|
|
|
|
|
boundary.check_face_timeout(); |
|
|
|
|
|
|
|
|
|
|
|
// work out primary instance - first sensor returning good data
|
|
|
|
// work out primary instance - first sensor returning good data
|
|
|
|
for (int8_t i=num_instances-1; i>=0; i--) { |
|
|
|
for (int8_t i=num_instances-1; i>=0; i--) { |
|
|
|
if (drivers[i] != nullptr && (state[i].status == Status::Good)) { |
|
|
|
if (drivers[i] != nullptr && (state[i].status == Status::Good)) { |
|
|
@ -207,90 +212,46 @@ float AP_Proximity::distance_min() const |
|
|
|
// get distances in 8 directions. used for sending distances to ground station
|
|
|
|
// get distances in 8 directions. used for sending distances to ground station
|
|
|
|
bool AP_Proximity::get_horizontal_distances(Proximity_Distance_Array &prx_dist_array) const |
|
|
|
bool AP_Proximity::get_horizontal_distances(Proximity_Distance_Array &prx_dist_array) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
Proximity_Distance_Array prx_filt_dist_array; // unused
|
|
|
|
return false; |
|
|
|
return boundary.get_layer_distances(PROXIMITY_MIDDLE_LAYER, distance_max(), prx_dist_array, prx_filt_dist_array); |
|
|
|
} |
|
|
|
|
|
|
|
// get distances from backend
|
|
|
|
|
|
|
|
return drivers[primary_instance]->get_horizontal_distances(prx_dist_array); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// get number of layers.
|
|
|
|
|
|
|
|
uint8_t AP_Proximity::get_num_layers() const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return drivers[primary_instance]->get_num_layers(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// get raw and filtered distances in 8 directions per layer. used for logging
|
|
|
|
|
|
|
|
bool AP_Proximity::get_active_layer_distances(uint8_t layer, AP_Proximity::Proximity_Distance_Array &prx_dist_array, AP_Proximity::Proximity_Distance_Array &prx_filt_dist_array) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// get distances from backend
|
|
|
|
|
|
|
|
return drivers[primary_instance]->get_active_layer_distances(layer, prx_dist_array, prx_filt_dist_array); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// get total number of obstacles, used in GPS based Simple Avoidance
|
|
|
|
// get total number of obstacles, used in GPS based Simple Avoidance
|
|
|
|
uint8_t AP_Proximity::get_obstacle_count() const |
|
|
|
uint8_t AP_Proximity::get_obstacle_count() const |
|
|
|
{
|
|
|
|
{ |
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
return boundary.get_obstacle_count(); |
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return drivers[primary_instance]->get_obstacle_count(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// get vector to obstacle based on obstacle_num passed, used in GPS based Simple Avoidance
|
|
|
|
// get vector to obstacle based on obstacle_num passed, used in GPS based Simple Avoidance
|
|
|
|
bool AP_Proximity::get_obstacle(uint8_t obstacle_num, Vector3f& vec_to_obstacle) const |
|
|
|
bool AP_Proximity::get_obstacle(uint8_t obstacle_num, Vector3f& vec_to_obstacle) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
return boundary.get_obstacle(obstacle_num, vec_to_obstacle); |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return drivers[primary_instance]->get_obstacle(obstacle_num, vec_to_obstacle); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// returns shortest distance to "obstacle_num" obstacle, from a line segment formed between "seg_start" and "seg_end"
|
|
|
|
// returns shortest distance to "obstacle_num" obstacle, from a line segment formed between "seg_start" and "seg_end"
|
|
|
|
// used in GPS based Simple Avoidance
|
|
|
|
// returns FLT_MAX if it's an invalid instance.
|
|
|
|
bool AP_Proximity::closest_point_from_segment_to_obstacle(uint8_t obstacle_num, const Vector3f& seg_start, const Vector3f& seg_end, Vector3f& closest_point) const |
|
|
|
bool AP_Proximity::closest_point_from_segment_to_obstacle(uint8_t obstacle_num, const Vector3f& seg_start, const Vector3f& seg_end, Vector3f& closest_point) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
return boundary.closest_point_from_segment_to_obstacle(obstacle_num , seg_start, seg_end, closest_point); |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return drivers[primary_instance]->closest_point_from_segment_to_obstacle(obstacle_num, seg_start, seg_end, closest_point); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// get distance and angle to closest object (used for pre-arm check)
|
|
|
|
// get distance and angle to closest object (used for pre-arm check)
|
|
|
|
// returns true on success, false if no valid readings
|
|
|
|
// returns true on success, false if no valid readings
|
|
|
|
bool AP_Proximity::get_closest_object(float& angle_deg, float &distance) const |
|
|
|
bool AP_Proximity::get_closest_object(float& angle_deg, float &distance) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
return boundary.get_closest_object(angle_deg, distance); |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// get closest object from backend
|
|
|
|
|
|
|
|
return drivers[primary_instance]->get_closest_object(angle_deg, distance); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// get number of objects, used for non-GPS avoidance
|
|
|
|
// get number of objects, angle and distance - used for non-GPS avoidance
|
|
|
|
uint8_t AP_Proximity::get_object_count() const |
|
|
|
uint8_t AP_Proximity::get_object_count() const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
return boundary.get_horizontal_object_count(); |
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// get count from backend
|
|
|
|
|
|
|
|
return drivers[primary_instance]->get_horizontal_object_count(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// get an object's angle and distance, used for non-GPS avoidance
|
|
|
|
// get number of objects, angle and distance - used for non-GPS avoidance
|
|
|
|
// returns false if no angle or distance could be returned for some reason
|
|
|
|
|
|
|
|
bool AP_Proximity::get_object_angle_and_distance(uint8_t object_number, float& angle_deg, float &distance) const |
|
|
|
bool AP_Proximity::get_object_angle_and_distance(uint8_t object_number, float& angle_deg, float &distance) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!valid_instance(primary_instance)) { |
|
|
|
return boundary.get_horizontal_object_angle_and_distance(object_number, angle_deg, distance); |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// get angle and distance from backend
|
|
|
|
|
|
|
|
return drivers[primary_instance]->get_horizontal_object_angle_and_distance(object_number, angle_deg, distance); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// handle mavlink DISTANCE_SENSOR messages
|
|
|
|
// handle mavlink DISTANCE_SENSOR messages
|
|
|
@ -355,8 +316,8 @@ void AP_Proximity::log() |
|
|
|
Proximity_Distance_Array dist_array{}; // raw distances stored here
|
|
|
|
Proximity_Distance_Array dist_array{}; // raw distances stored here
|
|
|
|
Proximity_Distance_Array filt_dist_array{}; //filtered distances stored here
|
|
|
|
Proximity_Distance_Array filt_dist_array{}; //filtered distances stored here
|
|
|
|
auto &logger { AP::logger() }; |
|
|
|
auto &logger { AP::logger() }; |
|
|
|
for (uint8_t i = 0; i < get_num_layers(); i++) { |
|
|
|
for (uint8_t i = 0; i < boundary.get_num_layers(); i++) { |
|
|
|
const bool active = get_active_layer_distances(i, dist_array, filt_dist_array); |
|
|
|
const bool active = boundary.get_layer_distances(i, distance_max(), dist_array, filt_dist_array); |
|
|
|
if (!active) { |
|
|
|
if (!active) { |
|
|
|
// nothing on this layer
|
|
|
|
// nothing on this layer
|
|
|
|
continue; |
|
|
|
continue; |
|
|
|