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
Add ability to navigate using MAVLink vision messages #7980
Conversation
This is a really important feature. This will enable the ROS users to feed in the SLAM position estimates to ArduPilot. |
@@ -191,6 +191,19 @@ void SITL_State::wait_clock(uint64_t wait_time_usec) | |||
} | |||
} | |||
|
|||
#define streq(a, b) (!strcmp(a, b)) |
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.
can we remove this define ?
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.
it is used only once !
libraries/SITL/SIM_Vicon.cpp
Outdated
|
||
// push a reading into the socket... | ||
|
||
bool should_send_heartbeat = 0; |
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 look weird
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.
Yep, this means it never sends an heartbeat... (and it should be false in any case).
libraries/SITL/SIM_Vicon.h
Outdated
|
||
private: | ||
|
||
const uint8_t system_id = 17; |
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.
maybe add a todo for a param table to handle that
62773a6
to
a703171
Compare
On Wed, 21 Mar 2018, Pierre Kancir wrote:
+#define streq(a, b) (!strcmp(a, b))
can we remove this define ?
Only if we can get from somewhere else :-P
+
+ // push a reading into the socket...
+
+ bool should_send_heartbeat = 0;
this look weird
Will fix.
+ const uint8_t system_id = 17;
maybe add a todo for a param table to handle that
Done!
Force-pushed.
|
On Wed, 21 Mar 2018, Pierre Kancir wrote:
+#define streq(a, b) (!strcmp(a, b))
it is used only once !
So far :-)
But my sds021 branch would use it once rebased on this.
|
a703171
to
3467e5b
Compare
3467e5b
to
41887c1
Compare
@OXINARF, if you get a chance to review this that would be really really appreciated! |
As requested in #7997 by @peterbarker, I'm trying to test this functionality but running into some trouble. I'm able to send VISION_POSITION_ESTIMATE and ATT_POS_MOCAP messages generated by an Optitrack mocap system via mavros, and can view them in QGroundControl's MavLink inspector. I'm also able to run the preliminary tests without any problem. But on the actual system (pixhawk 2.1, custom quad frame, mavlink connection on Telem2), I never get the Parameters: mocap_message_tests.txt |
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.
Besides inline comments:
- why isn't this in EKF3? Looks like that could lead to a regression when we change to using it
- I have no issue with how SITL Vicon simulation is done, but it's different from other simulated devices
- SITL Vicon seems to have an old idea of keeping an observation history that is unused
libraries/AP_NavEKF2/AP_NavEKF2.cpp
Outdated
/* | ||
* Write position and quaternion data from an external navigation system | ||
* | ||
* pos : position in the RH navigation frame. Frame is assumed to be NED if frameIsNED is true. (m) |
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.
There is no frameIsNED argument.
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.
will fix
libraries/AP_NavEKF2/AP_NavEKF2.cpp
Outdated
* Write position and quaternion data from an external navigation system | ||
* | ||
* pos : position in the RH navigation frame. Frame is assumed to be NED if frameIsNED is true. (m) | ||
* quat : quaternion desribing the the rotation from navigation frame to 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.
desribing -> describing
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.
will fix
// handle yaw reset as special case | ||
extNavYawResetRequest = true; | ||
controlMagYawReset(); | ||
// handle height reset as sepcial case |
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.
sepcial -> special
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.
will fix
@@ -169,7 +169,8 @@ void NavEKF2_core::setAidingMode() | |||
// GPS aiding is the preferred option unless excluded by the user | |||
bool canUseGPS = ((frontend->_fusionModeGPS) != 3 && readyToUseGPS() && filterIsStable && !gpsInhibit); | |||
bool canUseRangeBeacon = readyToUseRangeBeacon() && filterIsStable; | |||
if(canUseGPS || canUseRangeBeacon) { | |||
bool canUseExtNav = readyToUseExtNav() && tiltAlignComplete; |
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.
tiltAlignComplete
is already checked in readyToUseExtNav
.
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.
will fix
@@ -500,7 +520,7 @@ void NavEKF2_core::updateFilterStatus(void) | |||
filterStatus.flags.takeoff = expectGndEffectTakeoff; // The EKF has been told to expect takeoff and is in a ground effect mitigation mode | |||
filterStatus.flags.touchdown = expectGndEffectTouchdown; // The EKF has been told to detect touchdown and is in a ground effect mitigation mode | |||
filterStatus.flags.using_gps = ((imuSampleTime_ms - lastPosPassTime_ms) < 4000) && (PV_AidingMode == AID_ABSOLUTE); | |||
filterStatus.flags.gps_glitching = !gpsAccuracyGood && (PV_AidingMode == AID_ABSOLUTE); // The GPS is glitching | |||
filterStatus.flags.gps_glitching = !gpsAccuracyGood && (PV_AidingMode == AID_ABSOLUTE) && !extNavUsedForPos; // The GPS is glitching |
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 doesn't make much sense to me, just because we are using external navigation, the GPS might be glitching anyway. If anything, it seems to make more sense in the line above, using_gps
.
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.
The problem is how that flag is used. With copter it causes a failsafe reversion into alt hold mode and will prevent takeoff. The EKF2 will never use external nav and GPS at the same time, so when external nav is being used, GPS status is irrelevant.
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.
The better way to describe the gps_glitching flag is being 'true when GPS glitching is affecting navigation accuracy'. I will update comments to make this clearer.
libraries/SITL/SIM_Vicon.h
Outdated
struct { | ||
const uint16_t observation_interval_ms = 20; | ||
// delay results by some multiplier of the observation_interval: | ||
const uint8_t observation_history_length = 0; |
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.
If this is const, how does it change? It looks unused...
libraries/SITL/SIM_Vicon.h
Outdated
const uint16_t observation_interval_ms = 20; | ||
// delay results by some multiplier of the observation_interval: | ||
const uint8_t observation_history_length = 0; | ||
ObjectArray<obs_elements> observation_history{observation_history_length}; |
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.
An array of 0?
libraries/SITL/SIM_Vicon.h
Outdated
Quaternion attitude; | ||
}; | ||
|
||
bool observation_history_initialised; |
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.
Unused
libraries/SITL/SIM_Vicon.cpp
Outdated
observation = new_obs; | ||
} else { | ||
vicon.observation_history.push(new_obs); | ||
vicon.last_observation_ms = now; |
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 should always be updated, not just when history would be used.
libraries/SITL/SIM_Vicon.h
Outdated
// we share channels with the ArduPilot binary! | ||
const uint8_t mavlink_ch = 17; | ||
|
||
uint32_t last_update_ms; |
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.
Unused
41887c1
to
0b90865
Compare
0b90865
to
7bf1a39
Compare
On Sat, 24 Mar 2018, Francisco Ferreira wrote:
* I have no issue with how SITL Vicon simulation is done, but it's
different from other simulated devices
I'm hoping to have other things act similarly. Notably the GPS stuff.
* SITL Vicon seems to have an old idea of keeping an observation history
that is unused
It does work, but is a compile-time change. I've pushed up a patch on top
which makes it a parameter instead ("reboot" required ;-) )
I was expecting this would go through the AP_VisualOdom library which
already have those parameters.
My understanding is that VisualOdometry (by its name if nothing else) will
work with deltas, not position estimates.
+ bool should_send_heartbeat = 0;
Yep, this means it never sends an heartbeat... (and it should be false in
any case).
This was a just-in-case-it's needed thing. I've commented it back in, so
it now sends heartbeats.
+ const uint8_t observation_history_length = 0;
If this is const, how does it change? It looks unused...
As noted, this was a compile-time option for testing.... it's now a
parameter.
+ bool observation_history_initialised;
Unused
Removed.
+ vicon.last_observation_ms = now;
This should always be updated, not just when history would be used.
Will fix.
+ uint32_t last_update_ms;
Unused
Will remove.
|
There was a bigger change under development for EKF3 that adds an additional state for scale factor estimation of monocular SLAM and VO. Adding changes from this PR to EKF3 would cause pain in rebasing. |
Merged after removing squashing the last commit and removing the, "DataFlash: Add debug loggin for EKF external nav fusion". Thanks @priseborough and @peterbarker! |
On Sat, 24 Mar 2018, vincekurtz wrote:
As requested in #7997 by @peterbarker, I'm trying to test this functionality but running into some trouble.
Thanks for testing!
I'm able to send VISION_POSITION_ESTIMATE and ATT_POS_MOCAP messages generated by an Optitrack mocap system via mavros, and can view them in
QGroundControl's MavLink inspector. I'm also able to run the preliminary tests without any problem.
Would be nice if we can get those fed into SITL!
But on the actual system (pixhawk 2.1, custom quad frame, mavlink connection on Telem2), I never get the APM: EKF2 IMU0 is using external nav data ...
messages. I'm guessing my setup is not quite right: any guidance would be much appreciated!
Are you convinced that mavlink connection was solid? I assume there were
two mavlink connections involved here? The tlog you sent through didn't
seem to be carrying vision data of any sort - and given the lack of target
ids I think it would have to.
Also missing is the XKCF message in the dataflash log - not one, and this
is probably same root cause as not getting the magic EKF-is-using
messages.
|
@peterbarker - I'm fairly certain the mavlink connection is solid, but I'm still unable to use ATT_POS_MOCAP or VISION_POSITION_ESTIMATE messages. I've set up a minimal working example using mavros, mavros_extras, python, and SITL as follows: Test ExampleSet up SITL:
Connect via mavros (using the px4 launch file because it enables the mocap_pose_estimate plugin by default - using a modified apm launch file gives the same results)
Run a python script that publishes to the test_pose_publisher.py:
ResultsBy putting I'm able to trace the progress of the (fake) mocap information as far as the |
@vincekurtz, it's really great that you're testing this, thanks! We think the issue may be the timestamps in the messages. They need to be synced up with the system time of the flight controller/ArduPilot. If the times are very far off the EKF will simply not consume the data. If you're using a Rover or Copter on a Pixhawk (or compatible) could you try this firmware? It's just master with two patches on top to ignore the time in the message and instead uses the system time. This won't work really well but it should basically work. https://github.com/rmackay9/rmackay9-ardupilot/commits/visp-log |
Logs from two flights using the patched firmware are attached. I was able hold altitude and position, but performance was relatively poor considering the accuracy of the mocap system. Altitude tended to drift up and down about a meter, and position hold was plagued by circular oscillations (especially evident in the second test flight). I'm not sure how much the poor performance is due to my setup (I didn't disable baro or mess with any of the EKF noise parameters) and how much is due to delays between measurement and use in the EKF that aren't taken into account. |
@vincekurtz, I guess you used a different firmware from the one I linked above? sorry, just having trouble finding the VISP message. I've merged the VISP message to master so you could just use master if you like. The system time isn't used in master though so using master requires ensuring that somehow the timestamps match the flight controller's time. |
@rmackay9, it looks like the VISP message doesn't get logged for the ATT_POS_MOCAP message type, which is what I was using. Specifically, the That should be an easy fix, but for now I'll try another test using the VICON_POSITION_ESTIMATE message, which does use |
Flight log using VICON_POSITION_ESTIMATE is attached. Performance was similar to using ATT_POS_MOCAP: there were large (but generally bounded) oscillations in position hold mode. |
@vincekurtz, we've got this PR which we hope will allow syncing the clocks between the two computers. It's being reviewed now and I hope it will go into master later this week. Txs for your patience and testing! |
We accept messages of various sorts, and feed the data into EKF2, which can fuse this data and allow us to navigate.
Preliminary instructions on testing this are here:
https://github.com/peterbarker/ardupilot_wiki/blob/vicon/dev/source/docs/using-sitl-for-ardupilot-testing.rst#testing-visual-positioning
Notes:
Edit: the earlier issue, in which the vehicle could not climb in Loiter mode while using external position estimates, has been resolved.