Raspberry Pi and SITL

1,010 views
Skip to first unread message

Christopher Cosmo Rogers

unread,
Apr 24, 2014, 12:05:00 PM4/24/14
to drones-...@googlegroups.com
Hi

So I have a project using a raspberry pi tracking a target with it's camera, and outputting roll, pitch and yaw.
My next step is to connect it to a APM2.5, however rather than crashing an actual craft, I want to demo it using the SITL simulator.

I've got that running fine, can connect flightgear, mavproxy, etc.

What I'm not to sure about it how to connect the raspberry pi to it. There seem to be quite a few topics about connecting a RPi to an APM, however little code following on from that, and none that I have found using TCP/UDP for mavlink (which I know can be done because mavproxy does it!)

The most useful example code I have found so far is
https://github.com/mavlink/c_uart_interface_example/blob/master/send_quad_commands.cpp

But that is connecting over serial, fine if I was using an actual APM, but I want to connect over TCP/UDP.

This
https://github.com/mavlink/mavlink/blob/master/examples/linux/mavlink_udp.c
uses UDP, but is the 'wrong' way around, it's connecting to QGroundControl. I want the opposite (so in effect the RPi becomes a ground control station sending the craft commands)


Also does anyone know for definte whether SET_ROLL_PITCH_YAW_THRUST ( https://pixhawk.ethz.ch/mavlink/#SET_ROLL_PITCH_YAW_THRUST ) is defiantly implemented in the latest version of ArduPilot? The internet is full of conflicting information, mostly saying it isn't :(
If it isn't what would be the best way to send 'input' to the apm from the RPi, using the RC message seems to be a popular choice, is this wise?


I'm writing this all in C/C++, which I am not an expert in by any measure. I have gone though the opencv demos, tutorials and examples to piece together the vision part, which seems to be working quite well now, but Mavlink doesn't seem to have the same level of demos and tutorials. Most of the examples that do exist (eg on the mavlink website) seem to be about using mavlink on your robot and then using an existing ground station, rather than making a realllllly simple ground station. If I have missed some them please point them out!

Thanks a bunch
Chris

jdennings

unread,
Apr 24, 2014, 5:15:39 PM4/24/14
to drones-...@googlegroups.com
 
I've looked at doing something similar a while back. Seems there are several ways of doing this, but all I've looked at was with Python (which also has a great OpenCV interface, along with the SimpleCV framework.)
 
One way is to run maxproxy (python)  with udp, and use a module to send flight commands (see maxproxy commands and example modules on github). Tridge's Cuav code  is also a great (and advanced) example. THe SITL examples  do something similar  but by running mavproxy commands in a script.
 
Another way,  if mavproxy commands are not granular enough for you, is to directly access lower level python functions in  mavproxy from your module. (As an example, I have not been able to figure out a  clean way  to use mavproxy top level commands to change a waypoint in real time, but it can be done at a lower level).
 
For the ultimate flexibility, you could write your own mavlink messages (by adding entries in the xml specifications and re-generating), and implementing the functionalility in maxproxy and the ardupilot-side flight code.
 
Finally, I've just looked at done_api (java or python) that appears to provide a neat and clean way to directly send flight commands.
 
I am new to this myself, so others chiming in would be welcome.

Ben Nizette

unread,
Apr 24, 2014, 9:02:21 PM4/24/14
to drones-...@googlegroups.com

Hi Chris

On Fri, Apr 25, 2014 at 12:05 AM, Christopher Cosmo Rogers <cosmo...@gmail.com> wrote:

What I'm not to sure about it how to connect the raspberry pi to it. There seem to be quite a few topics about connecting a RPi to an APM, however little code following on from that, and none that I have found using TCP/UDP for mavlink (which I know can be done because mavproxy does it!)

If you use the pymavlink library, or similar (possibly including the C++ binding, I don't know), you just need to give the MAVlink connection object an address starting with "udp://" rather than a serial device and that's it, that's the only difference between using a network and using serial from the GCS side.  Another option, the way I would do it myself, is to write your control code as a MAVProxy module, then you get access to all that infrastructure yourself.  It needs to be written in Python but there are heaps of examples in the MAVProxy/modules/ directory.

I'm assuming that you will not be running SITL on your RPi but on another machine on your network.  In that case, look at the scripts that are commonly used to start SITL (Tools/autotest/sim_arduplane.sh or more recently, Tools/autotest/sim_vehicle.sh) and find the line that actually starts MAVProxy.  Specify that your RPi will be a master by adding

--master=<rpi_ip:port>

Alongside the rest of the options.

That should be about it.  Run the script to start SITL with your new master option, run your mavlink program that's set up for UDP, you're away.
 


Also does anyone know for definte whether SET_ROLL_PITCH_YAW_THRUST ( https://pixhawk.ethz.ch/mavlink/#SET_ROLL_PITCH_YAW_THRUST ) is defiantly implemented in the latest version of ArduPilot? The internet is full of conflicting information, mostly saying it isn't :(
If it isn't what would be the best way to send 'input' to the apm from the RPi, using the RC message seems to be a popular choice, is this wise?

No, that command is not implemented, RC overrides aren't just a popular choice, they're the only choice (except implementing the other message yourself!).  If you're doing a MAVProxy module, check out the mavproxy_drop.py module that overrides an RC channel in order to drop a bottle, the same form will apply for you.

It's also worth mentioning that it's pretty well known that adding this kind of custom functionality is 1) nice to have and 2) hard.  There's some work being done at the moment to develop a specific high-level API for ArduPilot control that would address exactly this need.  But you're about 6 months too early :)


HTH.
  --Ben.

--
You received this message because you are subscribed to the Google Groups "drones-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kevin Hester

unread,
Apr 24, 2014, 9:21:36 PM4/24/14
to drones-discuss
Btw - if you want to write this in python, I think there is now a much easier way to go:


(This API will be evolving over the next few months but it is already pretty functional)


--

Ben Nizette

unread,
Apr 24, 2014, 10:01:48 PM4/24/14
to drones-...@googlegroups.com
Oh cool, that's the API to which I was referring at the end of my email but I didn't realise it was already as functional as it is.  Sweet, poking at that just became my mission for the afternoon.  Cheers Kevin!

Randy Mackay

unread,
Apr 24, 2014, 10:08:32 PM4/24/14
to drones-...@googlegroups.com

 

    I have also seen that SET_ROLL_PITCH_YAW_THRUST message and it does look like a good one to add support for.  In copter I suspect we’d make the get-pilot-desired-climb-rate and get-pilot-desired-lean-angles make the decision about whether to read in from the latest SET_ROLL_PITCH_YAW_THRUST value or the RC.

 

     We’d need to think it through so I’d like to discuss it with Kevin and Tridge on a future dev call.  I’m also quite consumed at the moment preparing for AC3.2-rc1.

 

-Randy

Ben Nizette

unread,
Apr 24, 2014, 10:17:44 PM4/24/14
to drones-...@googlegroups.com
I think Evan Slatyer at ANU was working on this for Plane a little while back, though I think he defined his own message that differed from this in the addition of a bitmask describing which channels to override and which should remain controlled by the active flight mode.  It also had a concept of timeouts and explicit release of override, both of which I think are important.  Something to chat about for 3.3+!

Ben.

Randy Mackay

unread,
Apr 25, 2014, 3:29:31 AM4/25/14
to drones-...@googlegroups.com

Chris,

 

     Also what you’re doing sounds very similar to what a number of us on the dev team need to do for the Sparkfun AVC which involves finding and popping 1m red balloons.

 

     A few of us will be using a slightly different set-up from what you’re using.  We will use:

1.       Odroid U3.  http://dev.ardupilot.com/wiki/odroid-via-mavlink/

2.       Drone-api (as mentioned by Kevin below)

3.       Coding in python and its embryonic form is here: https://github.com/rmackay9/ardupilot-balloon-finder/tree/master/scripts

 

-Randy

Daniel Frenzel

unread,
Apr 25, 2014, 4:56:13 AM4/25/14
to drones-...@googlegroups.com
I made a completely working project. Just GPS auto navigation is not implemented yet.
 

Daniel Frenzel

unread,
Apr 25, 2014, 4:58:24 AM4/25/14
to drones-...@googlegroups.com
I made 
- a Qt based GUI 
- Config scripts for debian
- firmware for the copter
- Based on the ArduPilot libaries

I would be lucky if someone would a contribute some code..

Greetings, Daniel

Daniel Frenzel

unread,
Apr 25, 2014, 5:00:13 AM4/25/14
to drones-...@googlegroups.com
Controlling works firstly over WiFi and if not possible over 3DR radio.
It is completely controllable over laptof with
- WASD 
-QE
and arrow keys :D

Christopher Cosmo Rogers

unread,
Apr 28, 2014, 9:06:15 AM4/28/14
to drones-...@googlegroups.com
Thanks for all the replies, I will have to look into more detail for each of them over the next week!

Cheers
Chris

Christopher Cosmo Rogers

unread,
May 8, 2014, 1:44:19 PM5/8/14
to drones-...@googlegroups.com
Hello again

So I've managed to bodge together some code from the example C code in mavlink (https://github.com/mavlink/c_uart_interface_example/blob/master/mavlink_serial.cpp) to use a socket instead, and I can get heartbeat messages (but not much else) (I assume from the simulator) over the network;

Received serial data: fe 09 fd 01 01 00 02 00 00 00 02 03 d1 04 03 b4 7c
Received message from serial with ID #0 (sys:1|comp:1):
Got heartbeat message
         type: 2
         autopilot: 3
         base_mode: 209
         system_status: 4
         mavlink_version: 3


So the next step is to try and send a message :)

I'm trying the mavlink_rc_channels_override message, but not having much luck. I think it might be to do with my target system and component ids?
This is the message code I have at the moment

mavlink_message_t message;

mavlink_rc_channels_override_t rccontrol;
               
rccontrol.chan1_raw = 1500; //roll
rccontrol.chan2_raw = 1900; //pitch
rccontrol.chan3_raw = 1500; //throttle
rccontrol.chan4_raw = 1500; //yaw
               
rccontrol.target_system = 1;
rccontrol.target_component = 1;
               
mavlink_msg_rc_channels_override_encode(1, 1, &message, &rccontrol);



I see a "New connection on serial port x" on the simulator, however the message doesn't seem to get though to the correct thing. Reading up it might because the target system and component are wrong? That or the local system_id and compent_id (although I thought I could just make these up?)


Do I need to send a regular heatbeat as well, as some places suggest? if so do these need to be regular, or can I just send 1 at the start?
I've manually armed the simulator using MavProxy at the moment, and using the rc channel pwn command (eg rc 1 1900) works and the copter flies around the map :)


I'd be grateful for any assistance


Cheers
Chris

On Thursday, 24 April 2014 17:05:00 UTC+1, Christopher Cosmo Rogers wrote:

Kevin Hester

unread,
May 9, 2014, 4:15:32 AM5/9/14
to drones-discuss
Hi Chris,

Some comments below...


On Thu, May 8, 2014 at 7:44 AM, Christopher Cosmo Rogers <cosmo...@gmail.com> wrote:
Hello again

So I've managed to bodge together some code from the example C code in mavlink (https://github.com/mavlink/c_uart_interface_example/blob/master/mavlink_serial.cpp) to use a socket instead, and I can get heartbeat messages (but not much else) (I assume from the simulator) over the network;

Received serial data: fe 09 fd 01 01 00 02 00 00 00 02 03 d1 04 03 b4 7c
Received message from serial with ID #0 (sys:1|comp:1):
Got heartbeat message
         type: 2
         autopilot: 3
         base_mode: 209
         system_status: 4
         mavlink_version: 3


So the next step is to try and send a message :)

I'm trying the mavlink_rc_channels_override message, but not having much luck. I think it might be to do with my target system and component ids?
This is the message code I have at the moment

mavlink_message_t message;

mavlink_rc_channels_override_t rccontrol;
               
rccontrol.chan1_raw = 1500; //roll
rccontrol.chan2_raw = 1900; //pitch
rccontrol.chan3_raw = 1500; //throttle
rccontrol.chan4_raw = 1500; //yaw
               
rccontrol.target_system = 1;
rccontrol.target_component = 1;
               
mavlink_msg_rc_channels_override_encode(1, 1, &message, &rccontrol);



Check to make sure you have the crc salt enabled (I forget the #def but it is important - it shifts the starting point for the crc calc based on msg id)
 

I see a "New connection on serial port x" on the simulator, however the message doesn't seem to get though to the correct thing. Reading up it might because the target system and component are wrong? That or the local system_id and compent_id (although I thought I could just make these up?)

The target sys & component look okay to me (same as I'm using successfully with various projects).  (Though sysid is set by param, the default is 1)

For your sending sys and component id - yes you can make these up (though usually 'gcs' seem to by convention to have decided on high sysids 250ish...
 


Do I need to send a regular heatbeat as well, as some places suggest? if so do these need to be regular, or can I just send 1 at the start?

You must send a heartbeat from your 'mock gcs' periodically or the vehicle will declare loss of link and cancel any rc-overrides (it 'should' do this - there are some edge cases in old code where it does not).  Send the heart beat about 1000ms or 500ms.

Here's how I am setting the heartbeat fields...

  // The custom mode we send in our outgoing heartbeat msgs
  var gcsCustomMode = 0
  var gcsBaseMode = MAV_MODE_FLAG.MAV_MODE_FLAG_SAFETY_ARMED | MAV_MODE_FLAG.MAV_MODE_FLAG_AUTO_ENABLED
  var autopilotCode = MAV_AUTOPILOT.MAV_AUTOPILOT_INVALID

  /**
   * Created lazily so our customMode can be changed if we want
   */
  def heartbeat = {
    val msg = new msg_heartbeat(systemId, componentId)

    msg.`type` = vehicleTypeCode
    msg.autopilot = autopilotCode
    msg.base_mode = gcsBaseMode
    msg.custom_mode = gcsCustomMode
    msg.system_status = MAV_STATE.MAV_STATE_ACTIVE
    msg.mavlink_version = 3 // Seems to be what ardupilot uses
    msg
  }

 
I've manually armed the simulator using MavProxy at the moment, and using the rc channel pwn command (eg rc 1 1900) works and the copter flies around the map :)

You might try looking at the packets that mavproxy is sending for the" rc 1 1900 command" - they are using the exact same rc overrides you are trying to use. ;-)
 


I'd be grateful for any assistance


Cheers
Chris

On Thursday, 24 April 2014 17:05:00 UTC+1, Christopher Cosmo Rogers wrote:
Hi

So I have a project using a raspberry pi tracking a target with it's camera, and outputting roll, pitch and yaw.
My next step is to connect it to a APM2.5, however rather than crashing an actual craft, I want to demo it using the SITL simulator.

I've got that running fine, can connect flightgear, mavproxy, etc.

What I'm not to sure about it how to connect the raspberry pi to it. There seem to be quite a few topics about connecting a RPi to an APM, however little code following on from that, and none that I have found using TCP/UDP for mavlink (which I know can be done because mavproxy does it!)

The most useful example code I have found so far is
https://github.com/mavlink/c_uart_interface_example/blob/master/send_quad_commands.cpp

But that is connecting over serial, fine if I was using an actual APM, but I want to connect over TCP/UDP.

This
https://github.com/mavlink/mavlink/blob/master/examples/linux/mavlink_udp.c
uses UDP, but is the 'wrong' way around, it's connecting to QGroundControl. I want the opposite (so in effect the RPi becomes a ground control station sending the craft commands)


Also does anyone know for definte whether SET_ROLL_PITCH_YAW_THRUST ( https://pixhawk.ethz.ch/mavlink/#SET_ROLL_PITCH_YAW_THRUST ) is defiantly implemented in the latest version of ArduPilot? The internet is full of conflicting information, mostly saying it isn't :(
If it isn't what would be the best way to send 'input' to the apm from the RPi, using the RC message seems to be a popular choice, is this wise?


I'm writing this all in C/C++, which I am not an expert in by any measure. I have gone though the opencv demos, tutorials and examples to piece together the vision part, which seems to be working quite well now, but Mavlink doesn't seem to have the same level of demos and tutorials. Most of the examples that do exist (eg on the mavlink website) seem to be about using mavlink on your robot and then using an existing ground station, rather than making a realllllly simple ground station. If I have missed some them please point them out!

Thanks a bunch
Chris

--

Ruud Siebierski

unread,
Sep 30, 2015, 6:11:57 PM9/30/15
to drones-discuss
Hi,

Did you get your setup to work with SITL and the RPi acting as GCS? I'm very curious on how to do that, because i want to accomplish exactly the same.
I read through the comments below, but can't get it to work.

Thanks,
Ruud


Op donderdag 24 april 2014 18:05:00 UTC+2 schreef Christopher Cosmo Rogers:

Christopher Cosmo Rogers

unread,
Oct 4, 2015, 2:59:56 PM10/4/15
to drones-discuss
I managed to get MAVProxy and Mission Planner connected to SITL over the network, but I never managed to get my own C code to work fully :(  (But also didn't manage to spend my time on solving it )

For MAVProxy and Mission Planner you should just be able to point it at the IP/Socket the SITL is running on.

Cheers
Chris

Ruud Siebierski

unread,
Oct 5, 2015, 3:44:35 AM10/5/15
to drones-...@googlegroups.com
Hi Chris,
Thanks for the reply.
Do you still know how to connect the mavproxy on the rpi to the SITL running on a different machine, over tcp? Because the SITL (Arducopter.elf) is listening on TCP port 5760, but I have no idea how to let mavproxy from RPi to connect to it. I read all the wiki's but still can't figure it out.

Best regards,
Ruud


--
You received this message because you are subscribed to a topic in the Google Groups "drones-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/drones-discuss/04n0dvZW3CM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to drones-discus...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages