Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Implemented use of optical flow for terrain estimation #597

Merged
merged 4 commits into from
May 15, 2019

Conversation

RomanBapst
Copy link
Contributor

@RomanBapst RomanBapst commented Apr 14, 2019

This PR allows optical flow measurements to be used for terrain estimation. I see the following two cases when this could be useful:

  • terrain estimation for fixed wing flight and auto land (potentially using the flow sensor at higher altitude and a lidar when close to the ground)
    @priseborough already did this in another project and I believe he had good success with the pmw3901 optical flow sensor.
  • enhancement of the detection logic for ground effect (see Pr ground effect zone PX4-Autopilot#11592 )

Flow measurements will only be fused in the terrain estimator if no range data is being fused and if the primary EKF is not fusing flow.
So far this has only been tested in SITL using iris_opt_flow model. Two logs are being provided, one where the terrain estimate is initialized to 50m on the ground in order to see if the filter recovers.
The second log shows a normal flight in position control over a flat surface. As the vehicle starts to move the terrain height becomes observable and the estimated terrain variance decreases. When the vehicle holds position the terrain variance increases again.

Terrain initialized to 50m
terrain_flow

Normal flight over flat ground
terrain_flow2

Logs:
Terrain initialized to 50m:
https://logs.px4.io/plot_app?log=e47c69ed-125c-4a82-a1df-dc0553904b63

Normal flight:
https://logs.px4.io/plot_app?log=a3864090-d60c-42af-8fc8-f8465ded7790

How to test:
Currently this feature can only be tested if optical flow in the main filter is deactivated and if no range data is available. Therefore, the following two steps are required for testing:

  1. Set EKF2_AID_MASK to only use GPS
  2. Comment out this line to avoid the system publishing range finder data.

Required action items:

  • test on real vehicle (multicopter and fixed wing)
  • - make sure we do not break existing optical flow & terrain estimation via lidar
  • - potentially adjust innovation gate size, optical flow measurement noise for robustness

@RomanBapst RomanBapst requested a review from priseborough April 14, 2019 11:47
}

// Calculate observation matrix for flow around the vehicle y axis
float Hy = -vel_body(0) * t0 /((_terrain_vpos - _state.pos(2)) * (_terrain_vpos - _state.pos(2)));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Guard against division by zero

@RomanBapst
Copy link
Contributor Author

Results from test flight on a fixed wing (Quanum observer, cruise speed 15 m/s), this was a flight over more or less flat terrain.
image

This is a zoom-in into the region when the vehicle landed. Noticed that at the time of touch-down the estimated distance to bottom is about 26cm (indicated by the spike in the accelerometer).
image

@RomanBapst
Copy link
Contributor Author

Results from a flight over a hill with altitudes above 100m.
image

@RomanBapst
Copy link
Contributor Author

Replay log for flat terrain:
https://logs.px4.io/plot_app?log=925aeea4-6679-4452-904e-1a1144e45bc2

Replay log for flight over hill:
https://logs.px4.io/plot_app?log=869142b1-7eeb-41d5-828a-3f7fefd848fe

NOTE
The optical flow orientation on these flight was not correct and need to be adjusted if you want to replay the logs. You can add the following code here

float helper = optflow_sample_new.flowRadXY(0);
optflow_sample_new.flowRadXY(0) = -optflow_sample_new.flowRadXY(1);
optflow_sample_new.flowRadXY(1) = helper;

@RomanBapst
Copy link
Contributor Author

This is a replayed log file of when the plane was flying over a hill:
https://logs.px4.io/plot_app?log=7b365163-79fc-46e7-8615-1b46d08db4a6

@@ -55,7 +55,10 @@ bool Ekf::initHagl()
_terrain_var = sq(_params.range_noise);
// success
return true;

} else if (_flow_for_terrain_data_ready) {
_terrain_vpos = _state.pos(2);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a guess unless we are on the ground. Might be better to set to height of origin as that is where terrain is most likely to be after takeoff.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If on ground, using current position is better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

// rotate into body frame
Vector3f vel_body = earth_to_body * vel_rel_earth;

float t0 = q0*q0 - q1*q1 - q2*q2 + q3*q3;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Which derivation did you use to obtain this? If you have a Matlab file, add it here and provide a link to it in the documentation: https://github.com/PX4/ecl/tree/master/EKF/matlab/scripts/Terrain%20Estimator

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@priseborough I added a python folder which has the script for the derivation.

float Hx = vel_body(1) * t0 /(pred_hagl * pred_hagl);

// Cacluate innovation variance
_flow_innov_var[0] = Hx * Hx * _terrain_var + R_LOS;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add protection against Hx * Hx * _terrain_var being less then zero.

Copy link
Collaborator

Choose a reason for hiding this comment

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

There are many places in code that touch _terrain_var and it is not forced to the non-negative immediately prior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

float Hy = -vel_body(0) * t0 /(pred_hagl * pred_hagl);

// Calculuate innovation variance
_flow_innov_var[1] = Hy * Hy * _terrain_var + R_LOS;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add protection against Hy * Hy * _terrain_var being less then zero.

Copy link
Collaborator

Choose a reason for hiding this comment

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

_terrain_var being protected against being negative above so should be OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@RomanBapst
Copy link
Contributor Author

@priseborough I addressed your comments.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants