mavlink / mavros

MAVLink to ROS gateway with proxy for Ground Control Station
Other
899 stars 994 forks source link

GPS altitude is different in subscriber and receiver #1414

Closed burak-yildizoz closed 3 years ago

burak-yildizoz commented 4 years ago

Issue details

As far as I know, MAVROS switched from mavros_msgs::GlobalPositionTarget to geographic_msgs::GeoPoseStamped, which is not documented in the wiki.

Publishing an altitude value with geographic_msgs::GeoPoseStamped corresponds a different height result in sensor_msgs::NavSatFix.

I found out from #1063 that the different is because geographic_msgs::GeoPoseStamped uses AMSL whereas the old publisher and the current subscriber uses WGS-84.

Subscribing to /mavros/altitude is a temporary solution for now, but detecting the problem is hard since most of the messages here are not even documented.

I suggest using a coherent subscriber-publisher pair. Also, the documentation is crucial, so it would be nice if you could spend some time on it to make it up-to-date.

MAVROS version and platform

Mavros: 1.1.0 ROS: Kinetic Ubuntu: 16.04

Autopilot type and version

[ ] ArduPilot [ X] PX4

Version: 1.10.1

Node logs

PX4 starting altitude

[Wrn] [gazebo_barometer_plugin.cpp:66] [gazebo_barometer_plugin] Using default home altitude of 488 m

/mavros/global_position/global

altitude: 526.05018872

/mavros/altitude

amsl: 488.039886475

Steady state result for target altitude 30 m

altitude    : 594.11 (from sensor_msgs/NavSatFix)
target_alt  : 556.14 (to geographic_msgs/GeoPoseStamped)
canberkgurel commented 4 years ago

One is using MSL while the other is using World Geodetic System (WGS84) ellipsoid, which does not perfectly follow the theoretical MSL. The MSL, approximated by an ellipsoid, is related to gravity or the center of mass of the earth. Discrepancies between a WGS84 ellipsoid, and the geoid vary with location [Reference]. I believe MAVROS is using GeographicLib to convert between the two [Reference].

abdupa61 commented 3 years ago

Merhaba Burak Bey,

Şu anda mavros GlobalPositionTarget() ile lat long ve alt yayını yapmaya çalışıyorum lakin gazeboda başlangıç altitude olarak rospy.Subscriber("/mavros/global_position/raw/fix", NavSatFix, globalPositionCallback) 'tan ~488 metre subscribe ediyorum. Aynı zamanda GlobalPositionTarget() ile lat long alt publish ederken de bahsettiğiniz konudan ötürü 47 metre fark ile publish etmek gerekiyor. Dolayısıyla size şöyle bir sorum olcak; Bu fark reelde de aynı mı olacak? Aynı olmayacaksa bu farkı bulmamın ve reelde lat long alt yayını yapmamın yöntemi nedir?

Teşekkür ederim.

burak-yildizoz commented 3 years ago

Merhaba Burak Bey,

Şu anda mavros GlobalPositionTarget() ile lat long ve alt yayını yapmaya çalışıyorum lakin gazeboda başlangıç altitude olarak rospy.Subscriber("/mavros/global_position/raw/fix", NavSatFix, globalPositionCallback) 'tan ~488 metre subscribe ediyorum. Aynı zamanda GlobalPositionTarget() ile lat long alt publish ederken de bahsettiğiniz konudan ötürü 47 metre fark ile publish etmek gerekiyor. Dolayısıyla size şöyle bir sorum olcak; Bu fark reelde de aynı mı olacak? Aynı olmayacaksa bu farkı bulmamın ve reelde lat long alt yayını yapmamın yöntemi nedir?

Teşekkür ederim.

Merhaba, Simülasyonda karşılaşılan bu durumla çok yüksek ihtimalde gerçekte de karşılaşılacaktır. GPS çeken bir ortamda dronu uçurmadan $ rostopic echo /mavros/altitude ve /mavros/global_position/global diyerek arada fark olup olmadığını görebilirsiniz. Eğer bahsettiğim çözümle drone simülasyonda 5 metre havada kalabiliyorsa gerçekte de pilot gözetiminde denemenizi öneririm. Direkt bu kodu kullanarak test edebilirsiniz. Türkçe mesaj atmanız her ne kadar hoş olsa da diğer insanların da faydalanabilmesi adına İngilizce kullanmak daha doğru olur :) Kolay gelsin.

abdupa61 commented 3 years ago

Merhaba Burak Bey, Şu anda mavros GlobalPositionTarget() ile lat long ve alt yayını yapmaya çalışıyorum lakin gazeboda başlangıç altitude olarak rospy.Subscriber("/mavros/global_position/raw/fix", NavSatFix, globalPositionCallback) 'tan ~488 metre subscribe ediyorum. Aynı zamanda GlobalPositionTarget() ile lat long alt publish ederken de bahsettiğiniz konudan ötürü 47 metre fark ile publish etmek gerekiyor. Dolayısıyla size şöyle bir sorum olcak; Bu fark reelde de aynı mı olacak? Aynı olmayacaksa bu farkı bulmamın ve reelde lat long alt yayını yapmamın yöntemi nedir? Teşekkür ederim.

Merhaba, Simülasyonda karşılaşılan bu durumla çok yüksek ihtimalde gerçekte de karşılaşılacaktır. GPS çeken bir ortamda dronu uçurmadan $ rostopic echo /mavros/altitude ve /mavros/global_position/global diyerek arada fark olup olmadığını görebilirsiniz. Eğer bahsettiğim çözümle drone simülasyonda 5 metre havada kalabiliyorsa gerçekte de pilot gözetiminde denemenizi öneririm. Direkt bu kodu kullanarak test edebilirsiniz. Türkçe mesaj atmanız her ne kadar hoş olsa da diğer insanların da faydalanabilmesi adına İngilizce kullanmak daha doğru olur :) Kolay gelsin.

Thank You for quick answering,

I have one more question. When I publish lat long alt with 'mavros/setpoint_raw/global', GlobalPositionTarget drone moving very fast. Is there any way to change moving speed for GlobalPositionTarget() publishing? (I mean drone speed in X and Y axis, not publishing speed )

Thank You a lot.

burak-yildizoz commented 3 years ago

I have one more question. When I publish lat long alt with 'mavros/setpoint_raw/global', GlobalPositionTarget drone moving very fast. Is there any way to change moving speed for GlobalPositionTarget() publishing? (I mean drone speed in X and Y axis, not publishing speed )

Unfortunately, I do not know how to change the speed by publishing 3D coordinates. All I know is the drone goes faster to further points and the speed is lower for the close ones. If you want to have more control over the drone, you need to use velocity setpoints. See PID control and example Python code.

abdupa61 commented 3 years ago

The other way is adding much waypoints. I hope it works.

Thank You very much. 🙋🏻‍♂️

canberkgurel commented 3 years ago

Use the MPC_XY_VEL_MAX parameter to set the max velocity of the drone.

abdupa61 commented 3 years ago

Hi again,

As you know, I am trying to send my quad to a lat long alt location using GlobalTargetAltitude. When I check altitude amsl with rostopic echo /mavros/altitude it returns 101.203 and /mavros/global_position/global returns 177. So, when I publish lat , long, altitude (bigger than 101 ex: for 7 meter 108) drone moving to lat long but altitude moving down. there was nothing wrong in simulation. Am I doing sth. wrong? How Do I send the drone to the height I want?

Thank You.

abdupa61 commented 3 years ago

Use the MPC_XY_VEL_MAX parameter to set the max velocity of the drone.

It works, Thank You so much for answering.

burak-yildizoz commented 3 years ago

@abdupa61 How do you use GlobalTargetAltitude in the first place? The first sentence in this issue is that MAVROS switched to geographic_msgs::GeoPoseStamped. I don't know if things are different in Python.

You should create a new issue and provide information about MAVROS version, full code and the results for different altitudes. I bet you can solve the problem by looking at the results for different altitudes.

murphym18 commented 3 years ago

@burak-yildizoz I got a chance to update the ros wiki. The setpoint_position/global section is up to date. Also, I added some notes about converting to/from AMSL and ellipsoid height (using C++ or python). They might be of interest to you (in case your unhappy with receiving altitude from "/mavros/altitude").

Anyways, I hope that helps. Thanks again for pointing this out to me in your comment here. I was pretty stuck.