-
Notifications
You must be signed in to change notification settings - Fork 13.6k
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
Scale obstacle distance with vehicle attitude for varying sensor orientations (Collision Prevention) #24107
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks ok, but there is a more efficient way to do this without passing by euler angles. You can compensate for a tilt by taking the last element of
PX4-Autopilot/src/lib/matrix/matrix/Quaternion.hpp
Lines 521 to 541 in 4db55cd
/** | |
* Corresponding body z-axis to an attitude quaternion / | |
* last orthogonal unit basis vector | |
* | |
* == last column of the equivalent rotation matrix | |
* but calculated more efficiently than a full conversion | |
*/ | |
Vector3<Type> dcm_z() const | |
{ | |
const Quaternion &q = *this; | |
Vector3<Type> R_z; | |
const Type a = q(0); | |
const Type b = q(1); | |
const Type c = q(2); | |
const Type d = q(3); | |
R_z(0) = 2 * (a * c + b * d); | |
R_z(1) = 2 * (c * d - a * b); | |
R_z(2) = a * a - b * b - c * c + d * d; | |
return R_z; | |
} | |
}; |
float sensor_yaw_body_rad = _sensorOrientationToYawOffset(distance_sensor, _obstacle_map_body_frame.angle_offset); | ||
float sensor_yaw_body_deg = math::degrees(wrap_2pi(sensor_yaw_body_rad)); | ||
|
||
// calculate the field of view boundary bin indices | ||
int lower_bound = (int)round((sensor_yaw_body_deg - math::degrees(distance_sensor.h_fov / 2.0f)) / BIN_SIZE); | ||
int upper_bound = (int)round((sensor_yaw_body_deg + math::degrees(distance_sensor.h_fov / 2.0f)) / BIN_SIZE); | ||
|
||
// unit vector of sensor orientation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// unit vector of sensor orientation |
The name of the variable is good enough
Quatf attitude_sensor_frame = vehicle_attitude; | ||
attitude_sensor_frame.rotate(Vector3f(0.f, 0.f, sensor_yaw_body_rad)); | ||
float sensor_dist_scale = cosf(Eulerf(attitude_sensor_frame).theta()); // verify | ||
// rotate sensor unit vector into vehicle body frame |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// rotate sensor unit vector into vehicle body frame |
@@ -425,6 +435,24 @@ CollisionPrevention::_addDistanceSensorData(distance_sensor_s &distance_sensor, | |||
} | |||
} | |||
|
|||
|
|||
// Function to rotate a 2D point by pitch and roll |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Function to rotate a 2D point by pitch and roll |
_rotatePointByPitchAndRoll is self explanatory
Solved Problem
Scaling of distance_reading to an obstacle was done under the assumption that the sensor was always mounted facing forward, so distance_reading was only scaled for pitch.
Solution
Orientation of sensor w.r.t vehicle body frame is taken into account, and the relevant vehicle attitude angles (pitch and/or roll) are used to scale the outputted distance.
Changelog Entry
For release notes:
Alternatives
We could also ...
Test coverage
Simulation/hardware testing logs: (Indoor, giving pitch/roll input manually for different sensor orientations @ fixed distance to flat wall)
Front facing:
Left facing (270 deg):
Roll scaling not super accurate in the 45deg case, probably because the placement of the sensor wasn't very exact. Can see it works well in the Left facing scenario.