diff --git a/libraries/AP_Proximity/AP_Proximity.cpp b/libraries/AP_Proximity/AP_Proximity.cpp index 8a6fe05466..4ecbf0f9f8 100644 --- a/libraries/AP_Proximity/AP_Proximity.cpp +++ b/libraries/AP_Proximity/AP_Proximity.cpp @@ -175,6 +175,13 @@ const AP_Param::GroupInfo AP_Proximity::var_info[] = { AP_GROUPINFO("2_YAW_CORR", 18, AP_Proximity, _yaw_correction[1], 0), #endif + // @Param: _LOG_RAW + // @DisplayName: Proximity raw distances log + // @Description: Set this parameter to one if logging unfiltered(raw) distances from sensor should be enabled + // @Values: 0:Off, 1:On + // @User: Advanced + AP_GROUPINFO("_LOG_RAW", 19, AP_Proximity, _raw_log_enable, 0), + AP_GROUPEND }; @@ -359,6 +366,16 @@ bool AP_Proximity::get_horizontal_distances(Proximity_Distance_Array &prx_dist_a return drivers[primary_instance]->get_horizontal_distances(prx_dist_array); } +// 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 uint8_t AP_Proximity::get_obstacle_count() const { @@ -368,6 +385,15 @@ uint8_t AP_Proximity::get_obstacle_count() const return drivers[primary_instance]->get_obstacle_count(); } +// 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 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 { diff --git a/libraries/AP_Proximity/AP_Proximity.h b/libraries/AP_Proximity/AP_Proximity.h index 54395a83c9..fc6cf8503a 100644 --- a/libraries/AP_Proximity/AP_Proximity.h +++ b/libraries/AP_Proximity/AP_Proximity.h @@ -94,6 +94,9 @@ public: // get distances in PROXIMITY_MAX_DIRECTION directions. used for sending distances to ground station bool get_horizontal_distances(Proximity_Distance_Array &prx_dist_array) const; + // get raw and filtered distances in 8 directions per layer. used for logging + bool 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; + // get total number of obstacles, used in GPS based Simple Avoidance uint8_t get_obstacle_count() const; @@ -112,6 +115,9 @@ public: uint8_t get_object_count() const; bool get_object_angle_and_distance(uint8_t object_number, float& angle_deg, float &distance) const; + // get number of layers + uint8_t get_num_layers() const; + // get maximum and minimum distances (in meters) of primary sensor float distance_max() const; float distance_min() const; @@ -135,6 +141,9 @@ public: Type get_type(uint8_t instance) const; + // true if raw distances should be logged + bool get_raw_log_enable() const { return _raw_log_enable; } + // parameter list static const struct AP_Param::GroupInfo var_info[]; @@ -166,6 +175,7 @@ private: AP_Int16 _yaw_correction[PROXIMITY_MAX_INSTANCES]; AP_Int16 _ignore_angle_deg[PROXIMITY_MAX_IGNORE]; // angle (in degrees) of area that should be ignored by sensor (i.e. leg shows up) AP_Int8 _ignore_width_deg[PROXIMITY_MAX_IGNORE]; // width of beam (in degrees) that should be ignored + AP_Int8 _raw_log_enable; // enable logging raw distances void detect_instance(uint8_t instance); }; diff --git a/libraries/AP_Proximity/AP_Proximity_Backend.cpp b/libraries/AP_Proximity/AP_Proximity_Backend.cpp index 7102aba8e4..60761cfff5 100644 --- a/libraries/AP_Proximity/AP_Proximity_Backend.cpp +++ b/libraries/AP_Proximity/AP_Proximity_Backend.cpp @@ -37,22 +37,13 @@ static_assert(PROXIMITY_MAX_DIRECTION <= 8, // get distances in PROXIMITY_MAX_DIRECTION directions horizontally. used for sending distances to ground station bool AP_Proximity_Backend::get_horizontal_distances(AP_Proximity::Proximity_Distance_Array &prx_dist_array) const { - // cycle through all sectors filling in distances and orientations - // see MAV_SENSOR_ORIENTATION for orientations (0 = forward, 1 = 45 degree clockwise from north, etc) - bool valid_distances = false; - prx_dist_array.offset_valid = 0; - for (uint8_t i=0; i + #define PROXIMITY_NUM_SECTORS 8 // number of sectors #define PROXIMITY_NUM_LAYERS 5 // num of layers in a sector #define PROXIMITY_MIDDLE_LAYER 2 // middle layer @@ -22,6 +24,7 @@ #define PROXIMITY_SECTOR_WIDTH_DEG (360.0f/PROXIMITY_NUM_SECTORS) // width of sectors in degrees #define PROXIMITY_BOUNDARY_DIST_MIN 0.6f // minimum distance for a boundary point. This ensures the object avoidance code doesn't think we are outside the boundary. #define PROXIMITY_BOUNDARY_DIST_DEFAULT 100 // if we have no data for a sector, boundary is placed 100m out +#define PROXIMITY_FILT_RESET_TIME 1000 // reset filter if last distance was pushed more than this many ms away class AP_Proximity_Boundary_3D { @@ -105,6 +108,12 @@ public: uint8_t get_horizontal_object_count() const; bool get_horizontal_object_angle_and_distance(uint8_t object_number, float& angle_deg, float &distance) const; + // get number of layers + uint8_t get_num_layers() const { return PROXIMITY_NUM_LAYERS; } + + // get raw and filtered distances in 8 directions per layer. + bool get_layer_distances(uint8_t layer_number, float dist_max, AP_Proximity::Proximity_Distance_Array &prx_dist_array, AP_Proximity::Proximity_Distance_Array &prx_filt_dist_array) const; + // sectors static_assert(PROXIMITY_NUM_SECTORS == 8, "PROXIMITY_NUM_SECTOR must be 8"); const uint16_t _sector_middle_deg[PROXIMITY_NUM_SECTORS] {0, 45, 90, 135, 180, 225, 270, 315}; // middle angle of each sector @@ -130,6 +139,12 @@ private: // The resultant is packed into a Boundary Location object and returned by reference as "face" bool convert_obstacle_num_to_face(uint8_t obstacle_num, Face& face) const WARN_IF_UNUSED; + // Apply low pass filter on the raw distance + void set_filtered_distance(const Face &face, float distance); + + // Return filtered distance for the passed in face + bool get_filtered_distance(const Face &face, float &distance) const; + Vector3f _sector_edge_vector[PROXIMITY_NUM_LAYERS][PROXIMITY_NUM_SECTORS]; Vector3f _boundary_points[PROXIMITY_NUM_LAYERS][PROXIMITY_NUM_SECTORS]; @@ -137,5 +152,7 @@ private: float _pitch[PROXIMITY_NUM_LAYERS][PROXIMITY_NUM_SECTORS]; // pitch angle in degrees to the closest object within each sector and layer float _distance[PROXIMITY_NUM_LAYERS][PROXIMITY_NUM_SECTORS]; // distance to closest object within each sector and layer bool _distance_valid[PROXIMITY_NUM_LAYERS][PROXIMITY_NUM_SECTORS]; // true if a valid distance received for each sector and layer + uint32_t _last_update_ms[PROXIMITY_NUM_LAYERS][PROXIMITY_NUM_SECTORS]; // time when distance was last updated + LowPassFilterFloat _filtered_distance[PROXIMITY_NUM_LAYERS][PROXIMITY_NUM_SECTORS]; // low pass filter };