MAVLink Linux/QNX/MacOs Integration Tutorial (UDP)

Overview

This program was written to test the udp connection to QGroundControl. It will send the necessary mavlink packets to QGroundControl in order to cause a new UAS object to be created and allow packets to be sent back. The code can be compiled unchanged on Linux, QNX and MacOS. Please find the correct GCC commands at the bottom of the page.

Note: In order for this code to work you must adjust the IP address of the host running qgroundcontrol. The default address is localhost (127.0.0.1), but you can change it by giving a parameter to the process, so that is the address to change.

To get full help, type after you compiled the code:

./mavlink_udp --help

You can find a full description of the details of the MAVLink protocol in the wiki.

Connection / Stateless

 MAVLink is stateless, but QGroundControl tracks if a system is alive using the heartbeat message. Therefore make sure to send a heartbeat every 60, 30, 10 or 1 second (1 Hz is recommended, but not required). A system will only be considered connected (and the views created for it) once a heartbeat arrives.

C-Code (MAVLink Version v1.0.0)

mavlink_udp.c
/*******************************************************************************
Copyright (C) 2010 Bryan Godbolt godbolt ( a t ) ualberta.ca
 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
 
****************************************************************************/
/*
This program sends some data to qgroundcontrol using the mavlink protocol. The sent packets
cause qgroundcontrol to respond with heartbeats. Any settings or custom commands sent from
qgroundcontrol are printed by this program along with the heartbeats.
 
 
I compiled this program sucessfully on Ubuntu 10.04 with the following command
 
gcc -I ../../pixhawk/mavlink/include -o udp-server udp-server-test.c
 
the rt library is needed for the clock_gettime on linux
*/
/* These headers are for QNX, but should all be standard on unix/linux */
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#if (defined __QNX__) | (defined __QNXNTO__)
/* QNX specific headers */
#include <unix.h>
#else
/* Linux / MacOS POSIX timer headers */
#include <sys/time.h>
#include <time.h>
#include <arpa/inet.h>
#endif
 
/* This assumes you have the mavlink headers on your include path
or in the same folder as this source file */
#include <mavlink.h>
 
 
#define BUFFER_LENGTH 2041 // minimum buffer size that can be used with qnx (I don't know why)
 
uint64_t microsSinceEpoch();
 
int main(int argc, char* argv[])
{
 
char help[] = "--help";
 
 
char target_ip[100];
 
float position[6] = {};
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in gcAddr;
struct sockaddr_in locAddr;
//struct sockaddr_in fromAddr;
uint8_t buf[BUFFER_LENGTH];
ssize_t recsize;
socklen_t fromlen;
int bytes_sent;
mavlink_message_t msg;
uint16_t len;
int i = 0;
//int success = 0;
unsigned int temp = 0;
 
// Check if --help flag was used
if ((argc == 2) && (strcmp(argv[1], help) == 0))
{
printf("\n");
printf("\tUsage:\n\n");
printf("\t");
printf("%s", argv[0]);
printf(" <ip address of QGroundControl>\n");
printf("\tDefault for localhost: udp-server 127.0.0.1\n\n");
exit(EXIT_FAILURE);
}
 
 
// Change the target ip if parameter was given
strcpy(target_ip, "127.0.0.1");
if (argc == 2)
{
strcpy(target_ip, argv[1]);
}
 
 
memset(&locAddr, 0, sizeof(locAddr));
locAddr.sin_family = AF_INET;
locAddr.sin_addr.s_addr = INADDR_ANY;
locAddr.sin_port = htons(14551);
 
/* Bind the socket to port 14551 - necessary to receive packets from qgroundcontrol */
if (-1 == bind(sock,(struct sockaddr *)&locAddr, sizeof(struct sockaddr)))
{
perror("error bind failed");
close(sock);
exit(EXIT_FAILURE);
}
 
/* Attempt to make it non blocking */
if (fcntl(sock, F_SETFL, O_NONBLOCK | FASYNC) < 0)
{
fprintf(stderr, "error setting nonblocking: %s\n", strerror(errno));
close(sock);
exit(EXIT_FAILURE);
}
 
 
memset(&gcAddr, 0, sizeof(gcAddr));
gcAddr.sin_family = AF_INET;
gcAddr.sin_addr.s_addr = inet_addr(target_ip);
gcAddr.sin_port = htons(14550);
 
 
 
for (;;)
{
 
/*Send Heartbeat */
mavlink_msg_heartbeat_pack(1, 200, &msg, MAV_TYPE_HELICOPTER, MAV_AUTOPILOT_GENERIC, MAV_MODE_GUIDED_ARMED, 0, MAV_STATE_ACTIVE);
len = mavlink_msg_to_send_buffer(buf, &msg);
bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
 
/* Send Status */
mavlink_msg_sys_status_pack(1, 200, &msg, 0, 0, 0, 500, 11000, -1, -1, 0, 0, 0, 0, 0, 0);
len = mavlink_msg_to_send_buffer(buf, &msg);
bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof (struct sockaddr_in));
 
/* Send Local Position */
mavlink_msg_local_position_ned_pack(1, 200, &msg, microsSinceEpoch(),
position[0], position[1], position[2],
position[3], position[4], position[5]);
len = mavlink_msg_to_send_buffer(buf, &msg);
bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
 
/* Send attitude */
mavlink_msg_attitude_pack(1, 200, &msg, microsSinceEpoch(), 1.2, 1.7, 3.14, 0.01, 0.02, 0.03);
len = mavlink_msg_to_send_buffer(buf, &msg);
bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
 
 
memset(buf, 0, BUFFER_LENGTH);
recsize = recvfrom(sock, (void *)buf, BUFFER_LENGTH, 0, (struct sockaddr *)&gcAddr, &fromlen);
if (recsize > 0)
{
// Something received - print out all bytes and parse packet
mavlink_message_t msg;
mavlink_status_t status;
 
printf("Bytes Received: %d\nDatagram: ", (int)recsize);
for (i = 0; i < recsize; ++i)
{
temp = buf[i];
printf("%02x ", (unsigned char)temp);
if (mavlink_parse_char(MAVLINK_COMM_0, buf[i], &msg, &status))
{
// Packet received
printf("\nReceived packet: SYS: %d, COMP: %d, LEN: %d, MSG ID: %d\n", msg.sysid, msg.compid, msg.len, msg.msgid);
}
}
printf("\n");
}
memset(buf, 0, BUFFER_LENGTH);
sleep(1); // Sleep one second
}
}
 
 
/* QNX timer version */
#if (defined __QNX__) | (defined __QNXNTO__)
uint64_t microsSinceEpoch()
{
 
struct timespec time;
 
uint64_t micros = 0;
 
clock_gettime(CLOCK_REALTIME, &time);
micros = (uint64_t)time.tv_sec * 1000000 + time.tv_nsec/1000;
 
return micros;
}
#else
uint64_t microsSinceEpoch()
{
 
struct timeval tv;
 
uint64_t micros = 0;
 
gettimeofday(&tv, NULL);
micros = ((uint64_t)tv.tv_sec) * 1000000 + tv.tv_usec;
 
return micros;
}
#endif

Compilation

On Ubuntu Linux and Mac OS:
Adjust the relative path to your MAVLink folder, and then compile.

gcc -I ../../include/common -o mavlink_udp mavlink_udp.c

On QNX: Point the include path to the mavlink includes

gcc -I ../../include/common -lsocket -o mavlink_udp mavlink_udp.c

最新文章

  1. 网购vs实体店购物 [20161226]
  2. 在64位系统上不能安装Matlab notebook的解决方案
  3. 自定义控件之 TextBox
  4. [转]oracle 10g数据泵之impdp-同时导入多个文件
  5. node.js npm权限问题try running this command again as root/Administrator.
  6. HDU1016 Prime Ring Problem(DFS回溯)
  7. PreparedStatement批量(batch)插入数据
  8. VC6.0 编译 gdlib 库
  9. HighlightingSystem插件使用(边缘发光)
  10. JSP标准标签库(JSTL)--JSTL简介与安装
  11. C#中的多线程超时处理实践
  12. neo4j语法
  13. 20款最好的JavaScript开发框架
  14. mybatis学习系列--逆向工程简单使用及mybatis原理
  15. JS高级 - 面向对象3(面向过程改写面向对象)
  16. 18,EasyNetQ-使用替代DI容器
  17. Python2.7.14安装和pip配置安装及虚拟环境搭建
  18. 题目1004:Median(qsort函数自定义cmp函数)
  19. Android学习之一
  20. kubernetes挂载ceph rbd和cephfs的方法

热门文章

  1. python的copy模块
  2. 题解51nod1515——明辨是非
  3. 【性能测试】:JVM内存监控策略的方法,以及监控结果说明
  4. wusir FTP与HTTP文件传输之TCP Packet解析
  5. (转).NET技术大系概览 (迄今为止最全的.NET技术栈)
  6. Git提交项目到GitHub
  7. JavaScript设计模式-14.组合模式实现
  8. c++ 同步阻塞队列
  9. Windump 的用法/Windump 是什么?
  10. 《Think Python》第16章学习笔记