I have been asked a few times now how I got my GCS basics up and running. MAVLink is a rather complicated protocol to implement. The documentation is rather thin and partially outdated... Not an easy thing, if you are no experienced developer...
I'm no pro developer by a long shot. I speak reasonably well C and I did some smaller projects in JAVA. All in all, I can hold my own but can't do nor understand really fancy stuff. Without the help of Pat Hickey, who answered many of my questions on the mailing list, I wouldn't have gotten very far, so first of all, thanks again to him and the others!
Now, how do we get a MAVLink interpreter going?
The first thing to do would be to snatch a copy of the GCS_MAVLink library from the Arducopter project. You will also need AP_Common, AP_Math and FastSerial for dependencies. FastSerial must be the first to be included in your sketch.
Then, go an grab the code of ArduStationII. When you have that, open 2 windows: One with the code of MAVLink.pde from ArduStation2, the other in the GCS_MAVLink library subdir include/mavlink/v1.0/common/
Then, in MAVLink.pde, look at void gcs_handleMessage(mavlink_message_t* msg). This function is called by gcs_update and does the main decoding work. Basically, it's a huge switch-case block which switches on the message id of the received package. Let's have a look at one case block:
case MAVLINK_MSG_ID_ATTITUDE:
{
// decode
mavlink_attitude_t packet;
mavlink_msg_attitude_decode(msg, &packet);
pitch = toDeg(packet.pitch);
yaw = toDeg(packet.yaw);
roll = toDeg(packet.roll);
break;
}
That doesn't look so complicated, does it? ArduStationII works mainly with global variables for all the interesting parameters. So what they do is, for everything they want, they knit a case block, fishing for the right message id, then call the respective decode method and assign the values to their global variables.
Let's have a look at something that isn't included in ArduStationII. In the common directory, search for mavlink_msg_vfr_hud.h and open it in an editor.
The very first thing in this file is the definition of what's in a MAVLINK_MSG_VFR_HUD packet:
typedef struct __mavlink_vfr_hud_t
{
float airspeed; ///< Current airspeed in m/s
float groundspeed; ///< Current ground speed in m/s
float alt; ///< Current altitude (MSL), in meters
float climb; ///< Current climb rate in meters/second
int16_t heading; ///< Current heading in degrees, in compass units (0..360, 0=north)
uint16_t throttle; ///< Current throttle setting in integer percent, 0 to 100
} mavlink_vfr_hud_t;
Let's say, we want the heading... If you scroll down a bit, you find the decode function...
static inline void mavlink_msg_vfr_hud_decode(const mavlink_message_t* msg, mavlink_vfr_hud_t* vfr_hud)
Seems, like we have everything. Now you just need to define a global variable for the heading...
int heading;
and write the respective case block:
case MAVLINK_MSG_ID_VFR_HUD:
{
mavlink_vfr_hud_t packet;
mavlink_msg_vfr_hud_decode(msg, &packet);
heading = packet.heading;
break;
}
Now there is only one more thing to do. Normally, the APM sends the VFR_HUD message rather rarely. You have to tell it to do it more often. In MAVLink.pde, scroll down until you find the start_feeds function. VFR_HUD is a stream in the EXTRA2 category ;). You can find out, which message stream is in which category from the GCS_MAVLink.pde in the Arducopter project :).
Have fun coding!
Comments
SO I was saying that I have no idea that weather I should use the complete code and include all the libraries. Plus can I access the values only on the serial port monitor?
I am a beginner and any help would be appreciated.
I want to read the basic paramters from APM like imu, roll,pitch yaw etc. I want to get this data through an Arduino Uno. I have no idea ho
I want to read the basic paramters from APM like imu, roll,pitch yaw etc. I want to get this data through an Arduino Uno. I have no idea ho
That depends what you want to do. Read the code of ArduStation :).
Stefan,
Am I adding this to MAVLink.pde or am I creating a separate sketch that uses the above and calls the correct libraries?
@Edit to previous post: The telemetry is attached to APM 2.5 as usual. I am just interfacing RPi for some networking needs and alongside RPi has a small camera attached which also I wish to control via GCS with my custom (say MavLink) commands..
Eagerly jumping to hear answers :)
Hi,
Good tutorial, thank you. I am interfacing Raspberry PI with APM 2.5. Can someone tell me how do I communicate with MaVLink between these two boards, change some values in real-time (like change mode from Stabilize-> Loiter) and still interact with the Mission Planner (GCS) on my laptop?
There are so many out there ROS, MavProxy, MavLink. Which is more suitable and why?
Any help is appreciated.
Ignore my last comment, have worked it out :)
so close but yet so far... sorry to be a complete noob but how do I get the code from github? All it lets me do is navigate down the file structure?
Thanks a lot! should help with my RPi GCS