VISION_POSITION_ESTIMATE not appearing in QGroundControl

Thanks a lot for your explanation, I remain with a doubt, when indoor which values I have to pass to SET_GPS_GLOBAL_ORIGIN?

@anbello: You can pass any value you’d like, but I’d recommend passing your real lat/long coordinates. ArduPilot will use these values to determine the magnetic declination (via a simple look-up table), so if you use a location that is distant from where you are, you will have inaccurate compass headings. Here is the code I use:

mavlink::common::msg::SET_GPS_GLOBAL_ORIGIN gpo;
gpo.target_system = m_uas->get_tgt_system();
// gpo.time_boot_ms = stamp.toNSec() / 1000;    #TODO: requires Mavlink msg update
gpo.latitude = 37.2343 * 1E7;
gpo.longitude = -115.8067 * 1E7;
gpo.altitude = 610.0 * 1E3; // roughly 610m above sea level

As Randy mentioned, this can also be done in Mission Planner, but it has to be done every time your controller (in my case, a PixHawk2) is powered on. So I find it more convenient to do it on code.

This message only needs to be sent once, and is only used to initialize the EKF. All of our control is local; we never use or query the global position estimates.

LOL Love this place … It smells like OuterSpace and Skunk !!! :wink:

1 Like

@jeff_null thanks a lot now is all clear

@jeff_null VISION_POSITION_ESTIMATE message get seven parameters: t, x, y, z, r, p, y whereas VISION_POSITION_DELTA get nine parameters t, delta_t, delta_x, delta_y, delta_z, delta_r, delta_p, delta_y, confidence. I would like to know how did you manage this.

@rmackay9 I would like to know if VISION_POSITION_DELTA will be the only message for visual odometry in Ardupilot or do you think that VISION_POSITION_ESTIMATE will be implemented, it could be more simple to use because it doesn’t need any modification in mavros code.

Thanks
Andrea

1 Like

@anbello I cannot agree more with you, not having the standard VISION_POSITION_ESTIMATE message implemented is problematic because it prevent usage of standard Visual Odometry systems.

@rmackay9 I think that you plan to push in that direction with next GSOC
List of Suggested Projects for GSoC 2024 — Dev documentation

  • Object Avoidance improvements for Multicopters and Rovers including adding occupancy grid using OctoMap or ROS.
  • Improve ROS integration and documentation

@fnoop, I guess you agree with this too :wink:

3 Likes

@anbello, @ppoirier,

Yes, in fact, it’s already on @priseborough’s list. I think it’s 2nd on his list so hopefully it won’t be too long. My guess is it’s several weeks away still but not months and months.

2 Likes

I chatted with Paul and we’re going to bump up the priority on getting support for the vision-position-estimate message into ardupilot.

2 Likes

@rmackay9 that is great news !!

@anbello As you note, VISION_POSITION_DELTA requires seven parameters: the position delta, the rotation delta, and a confidence value. The confidence value is a measurement of your visual odometry quality and accuracy, that should range from 0 to 100. I pass in ‘90,’ because my visual odometry system is pretty good, but I haven’t noticed different results if I pass in ‘50’ or ‘70.’

The position delta is easy: it’s the vector from the previous position to the current position in the frame of reference of the previous position. Thus, moving in straight line always gives you +X (we’re in a NED frame). Moving laterally to the right would give us +Y, etc.

Rotation is trickier, and I’m still not certain I’m doing it correctly. It should be just the rotation delta in the same frame of reference as the position; i.e. a triplet of Euler angles about the local X, Y and Z axes. However, in MAVROS the rotation is flipped 180 degrees around the X (forward) axis before the absolute visual pose is sent. (There is no documentation as to why this is.) So, should the vision delta also be computed in this flipped (NWU) frame of reference? I don’t know.

Thanks @jeff_null for detailed explanation, now I have to pass from theory to practice :slight_smile:
Thanks @rmackay9 when for the vision-position-estimate message will be supported in ardupilot this stuff will be easier, also for Jeff.

Something else to be aware of: if your visual odometry system provides updates slower than 10 Hz, I suspect the EKF sensor fusion will not work properly. There’s a hard cutoff, hardcoded within the ring buffer’s definition of ‘recall’, that will ignore visual odometry (or any body odometry) poses that are older than 100ms (since the last EKF update).

I am doing the same, were you able to do this with apm firmware. I did it with px4 but I need to do it with apm.

Hey @jeff_null, thanks for a detailed explanation here. I also wanted to know the rostopic that I need to check to see what I am getting as an output when /mavros/vision_pose/pose is sent as an input.
In case of PX4, it is /mavros/local_position/pose because there we use something called LPE (which you probably know). What rostopic should I check here?

@jeff_null are you sure that we need to have local* white listed in the mavros apm plugin file because APM does not have a local position estimation module.

The EKF-fused pose should still be published as ‘/mavros/local_position/pose’. It is on my system, at least. And I’m not 100% sure about needing the local* plugin whitelisted; I will try without it.

Hey @jeff_null, thanks for the response. Did you check if you have the local* plugin whitelisted? Please let me know.

Would you mind to share your apm_config and apm_pluginlists with me? and also the vision_position_estimate.cpp if possible.

@jeff_null in which part of the vision_pose_estimate.cpp do you set origin of the GPS coordinates. I have done it in the void initialize() function, is that okay?

Here is how it looks in my vision_pose_estimate.cpp code:

    void initialize(UAS &uas_)
	{
		PluginBase::initialize(uas_);
        mavlink::common::msg::SET_GPS_GLOBAL_ORIGIN gpo;
        gpo.target_system = m_uas->get_tgt_system();
        // gpo.time_boot_ms = stamp.toNSec() / 1000;    #TODO: requires Mavlink msg update
        gpo.latitude = 30.6197674;
        gpo.longitude = -96.3414215 ;
        gpo.altitude = 99.9674829152; 
		bool tf_listen;

		// tf params
		sp_nh.param("tf/listen", tf_listen, false);
		sp_nh.param<std::string>("tf/frame_id", tf_frame_id, "map");
		sp_nh.param<std::string>("tf/child_frame_id", tf_child_frame_id, "vision_estimate");
		sp_nh.param("tf/rate_limit", tf_rate, 10.0);
		old_x = old_y = old_z = old_roll = old_pitch = old_yaw = old_time = 0;
        flag_var = false;
		if (tf_listen) {
			ROS_INFO_STREAM_NAMED("vision_pose", "Listen to vision transform " << tf_frame_id
						<< " -> " << tf_child_frame_id);
			tf2_start("VisionPoseTF", &VisionPoseEstimatePlugin::transform_cb);
		}
		else {
			vision_sub = sp_nh.subscribe("pose", 10, &VisionPoseEstimatePlugin::vision_cb, this);
			vision_cov_sub = sp_nh.subscribe("pose_cov", 10, &VisionPoseEstimatePlugin::vision_cov_cb, this);
		}
	}

@jeff_null How exactly did you send the ‘mavlink::common::msg::SET_GPS_GLOBAL_ORIGIN’ message ? I think the code snippet you have posted here just sets the value for the above message type but how to send it, using what command?