For my current project, I would like to send telemetry/commands between the AMP2.0 and the computer via ethernet/wifi.  The ethernet connection would replace the serial connection typically used by most folks.  If I could find where the call to "Serial3.write()" occurs in the code, I could replace it with "Udp.sendpacket()", or something similar.  Does anyone have any suggestions?

Views: 1515

Reply to This

Replies to This Discussion

... in other words, does anyone know what changes are necessary to make Mavlink communicate over ethernet instead of serial?

You'll find everything goes through the MAVLink library, but that in turn calls user-supplied functions to actually send to serial port using the FastSerial library.  MAVLink facilitates "channels" which are virtual links rather than directly coding to ports. It's designed to be a portable protocol that compiles readily on a range of systems.

See http://qgroundcontrol.org/mavlink/start  - there's a link to some simple implementation code. Then you have to figure out how it's hooked into ArduPilot and modify it.

One nice thing about going UDP is the ethernet module will have its own buffer big enough for a whole packet, and probably several packets.  That can free up time/space constraints on the APM depending if/how you take advantage of it. 

Thank you for the reply; the link is great!  I had no idea MAVLink was a whole protocol separate from ArduPlane and APM.  I've done plenty of simple programming for robotic systems, but I have yet to work with FastSerial or MAVLink, so I will have to read up on those.  I like what you described about UDP freeing up resources on the APM.  Would you mind giving an idea on how to take advantage of that?

- FastSerial uses interrupt-driven code and a pair of circular buffers (in RAM) to ensure bytes are transmitted as quickly as possible, and received without problem while the main program is busy on other tasks. By removing that port from operation, you immediately save on the associated buffers. That's pretty straightforward.

- MAVLink has a checksum at the end of the packet, to test for integrity. Commands and data received would not be acted on until the whole packet is received and the checksum checked. With UDP, the ethernet checksum would already be confirmed and a damaged packet won't be presented. So, when receiving a packet you could interpret its content progressively without spooling the whole packet into a buffer. This may not be such a big saving, as most MAVLink messages are designed to be very compact and appear to be single-purpose. Also watch out for MAVLink's ability to re-order contained fields to align multi-byte words onto 4-byte boundaries.

- Packets for sending could also be assembled directly into the UDP interface rather than into a memory buffer. Initiate the UDP packet, send the header fields, send the payload fields, send the checksum (which you can accumulate as each byte is sent) and finish the UDP packet.

The direct inline packet processing would take more work, and involve more differences between your code and the standard builds. The net gain may be limited. However, if you're doing something that really needs the extra memory, or you're adding large/complex messages, it might make the difference required.

So the saving is three-fold then: first by removing the FastSerial buffers, second by allowing you to disregard the MAVLink checksum since it would be redundant, and third by eliminating the memory buffer for sending data.  Sounds good.

I'm still having trouble finding where exactly in the code I need to make the changes.  It looks like I make changes to "ArduPilot.pde" under the "GCS Selection" portion, then just take out everything dealing with FastSerial, but I'm not sure.  It'd be great to see if someone else is doing this; it's hard to believe that I'm the first to want to control APM 2.0 via UDP.

you are the first 

i am the second cody :( 

:P

no you want to look at the serial in the GCS library the update and send message commands would need to be changed to use UDP etc...  see GCS.h file (i think)

sorry the part which sends serial is in the library  http://code.google.com/p/ardupilot-mega/source/browse/libraries/GCS...

I have yet to discover how the code works in this respect, but I believe I've found a simple work-around solution: a UART to Ethernet converter.  The code stays just as it is, and the data is converted according to the settings on the converter.  Win win.

WIZnet W5100 Network Module with Mag Jack - WIZ811MJ

I've been using 3DR radios in addition to my wifi, which is a pain.  I'm going to get back on this and I will share my results when I have them.

Another project I'll be attempting: displaying video from an IP camera on the HUD.  I think there is a growing interest in using wifi devices, so these need to be done!

Hi Cody O,

I'm building a similar project like yours, and I would like to ask you for your expertish on that matter.

Did you manage to connect ardupilot to an ethernet device?

Did you try this one https://www.sparkfun.com/products/9473 or maybe something from here http://www.lantronix.com/device-networking/embedded-device-servers/ ?

Thanks

Hi,

All you have to do is basically to locate, in GCS_MAVLink.cpp:

void comm_send_buffer(mavlink_channel_t chan, const uint8_t *buf, uint8_t len)
{
switch(chan) {
case MAVLINK_COMM_0:
mavlink_comm_0_port->write(buf, len);
break;
case MAVLINK_COMM_1:
mavlink_comm_1_port->write(buf, len);
break;
default:
break;
}
}

and direct the output to your device instead. You can search for the mavlink_comm_port_X that you no longer use, and remove initialization of it:

GCS_MAVLink.pde:

void
GCS_MAVLINK::init(AP_HAL::UARTDriver *port)
{
GCS_Class::init(port);
if (port == (AP_HAL::BetterStream*)hal.uartA) {
mavlink_comm_0_port = port;
chan = MAVLINK_COMM_0;
}else{
mavlink_comm_1_port = port;
chan = MAVLINK_COMM_1;
}
_queued_parameter = NULL;
reset_cli_timeout();
}

In GCS_MAVLink,h there is a static inline void comm_send_ch(mavlink_channel_t chan, uint8_t ch) that you must change in the same way.

BTW, how is that connected? Which kind of interface on the CPU (if not serial) does it work with? Is this for the PX4?

For an example of a go-between thing that implements a stream and adds another comms protocol to MAVLink, you can have a look at my DroneCell mod: https://github.com/dongfang/ardupilot . I have run this on APM1 and 2 but not on PX4. There is nothing principal against it working on that too.

Of course, if you can implement BetterStreams around your ethernet streams you can just assing them directly to mavlink_comm_X_port and it should work without any other changes than that.

I am working on a redesign where the Streams don't have to be able to print so you will not have to implement all of BetterStream's printing stuff that MAVLink does not use anyway. Like in C, Java etc. I should get it finished one of these days..

Regards

Soren

Thanks for your answer,

so I need to get back to arduino programming to make this work :( 

but how about the hardware connection ! any idea ?

if I realy need all those connections: https://www.sparkfun.com/datasheets/DevTools/WIZnet/DEV-09473-Datas...

I think a new shield is needed ... 

RSS

© 2014   Created by Chris Anderson.

Badges  |  Report an Issue  |  Terms of Service