Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AP_Proximity: Add support for OBSTACLE_DISTANCE mavlink message #9418

Closed
wants to merge 4 commits into from

Conversation

eskaflon
Copy link
Contributor

This PR addresses issue #9269 as it adds support for the OBSTACLE_DISTANCE message, it repopulates the 72 sectors covered by this message into 8 like the DISTANCE_SENSOR, the message is then handled the same way that the DISTANCE_SENSOR is.

_distance_upward = packet.current_distance / 100.0f;
_last_upward_update_ms = AP_HAL::millis();
// get user configured yaw correction from front end
float yaw_correction = constrain_float(frontend.get_yaw_correction(state.instance), -360.0f, +360.0f);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@rmackay9
Copy link
Contributor

Just FYI, eskaflon is from elab.co.jp and I've been working with him on this. I've tested this on a real vehicle and it works. We've attached an RPLidarA2 to a TX2 on an AION Robotics rover and used ROS/mavros to send the lidar data to AP. That lidar data has been consumed by the Proximity library and resent down to the ground station so it appears like below in the MP "radar" view.
first-radar-view2

@OXINARF
Copy link
Member

OXINARF commented Sep 14, 2018

@rmackay9 Ah thanks @rmackay9, I wasn't aware of that. If it matters, I'm in the middle of review of this, I'll only finish tomorrow though.

@rmackay9
Copy link
Contributor

@OXINARF, great, thanks! it can wait so np. txs.

Copy link
Member

@OXINARF OXINARF left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides the inline comments, there is an assumption that the message always covers a 360 degrees range, but I don't see that anywhere in the MAVLink spec. The only things it says is the angle range of 72 possible distances.

uint8_t sector = packet.orientation;
_angle[sector] = sector * 45;
_distance[sector] = packet.current_distance / 100.0f;
if (msg->msgid == MAVLINK_MSG_ID_DISTANCE_SENSOR) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking: a switch would be nicer.

float increment = packet.increment;
if (packet.increment == 0) {
// assume an rplidar with 64 sectors
increment = 360.0f / 64.0f;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion we should reject a message without this information and not make assumptions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Txs for this review. OK, message will be rejected if the increment is zero.

for (uint8_t j = 0; j < total_distances; j++) {
if (!used[j]) {
const float packet_distance_m = packet.distances[j] / 100.0f;
const float mid_angle = wrap_360(increment * dir_correction * (0.5f + j) - increment_half + yaw_correction);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this math. Before the yaw and direction corrections, it was increment * (0.5f + j) - increment_half which is equal to increment * j:

increment * (0.5f + j) - increment_half =
increment * 0.5f + increment * j - increment_half =
increment_half + increment * j - increment_half =
increment * j

I think what was wanted was increment * j + increment_half. But this new version is more confusing:

increment * dir_correction * (0.5f + j) - increment_half + yaw_correction =
increment * dir_correction * 0.5f + increment * dir_correction * j - increment_half + yaw_correction =
dir_correction * increment_half + increment * dir_correction * j - increment_half + yaw_correction =
(dir_correction - 1) * increment_half + increment * dir_correction * j + yaw_correction

I think the old code bug just carried to the new code, but I might be wrong.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@OXINARF, I think you're right that the old formula was overly complicated. I've simplified it to, "const float mid_angle = wrap_360(j * increment * dir_correction + yaw_correction);". In each element of the OBSTACLE_DISTANCE the middle-angle is just the increment * j. So for example if increment is 5, the 0th element is pointing straight ahead or 0deg (-2.5deg ~ 2.5deg). the 1st element's middle is at 5deg (2.5deg ~ 7.5deg), etc.

libraries/AP_Proximity/AP_Proximity_MAV.cpp Show resolved Hide resolved
if (!used[j]) {
const float packet_distance_m = packet.distances[j] / 100.0f;
const float mid_angle = wrap_360(increment * dir_correction * (0.5f + j) - increment_half + yaw_correction);
float angle_diff = fabsf(wrap_180(_sector_middle_deg[i] - mid_angle));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I understand this, I think it's wrong to do it this way. Example:

  • increment: 11
  • distances: [900, 800, 700, 600, 100, ...]
  • our driver has 8 sectores with a width of 45 degrees
  • last sector from the MAVLink message is of 44-55 degrees range
  • so, I would say that, in theory, its distance should for go for the driver sectors 1 (0-45) and 2 (45-90)
  • but, the current code won't do count it for sector 1, which would be an issue since the sensor has detected an object at 1 meter that could at 44 degrees

In my opinion, if the MAVLink sector is within our driver sector, then it should be accounted for, not just check the MAVLink sector center.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

txs again for this review. I definitely hear what you're saying but I'm not sure it's worth supporting a single sector from the obstacle-distance message falling into two sectors within the AP_Proximity library. The reason is that in practice the obstacle-distance sectors are quite narrow and for object avoidance, we use AP_Proximity's _angle[i] and _distance[i] arrays to build a mini fence around the vehicle. the _angle[i] should never fall into two AP_Proximity sectors.

The change you're suggesting would only affect the radar view in the ground station (which doesn't use the _angle[i] array) and the difference would be quite subtle.

used[j] = true;
}
}
updated = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is always setting updated to true, making it useless. I'm not sure if there is a bug here or if it's simply not needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, definitely a bug. Moved up a few lines to the moment we update the _distance[i] and _angle[i]

@rmackay9
Copy link
Contributor

Re the assumption that the range is always 360deg - I think if the range is more than 360 there are two possibilities:

  • the increment is > 5degrees meaning there are extra blank elements at the end of the 72 element array. The sender should fill these elements with UINT16_MAX and then we will consume them correctly within AP_Proximity. Either they will be ignored because there are other shorter distances within the same sector or they will be beyond the sensor's max distance so they will not be used to stop the vehicle.
  • the increment is < 5degrees meaning less than 360 degree range is being provided. I've changed the total distance formula to, "const uint8_t total_distances = MIN(360.0f / increment, 72);" which I think will make us handle this case properly as well.

@rmackay9
Copy link
Contributor

I'm closing this PR in favour of this new PR which builds upon this one.

@rmackay9 rmackay9 closed this Sep 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants