依赖安装

Qt5.4

自从某个版本以后,编译 QGroundControl 要求 Qt5.4,Ubuntu 14.04 需要自行添加 ppa

1
2
$ sudo add-apt-repository ppa:beineri/opt-qt541-trusty
$ sudo apt-get install qt54tools qt54base qt54declarative qt54serialport qt54svg qt54webkit qt54quickcontrols qt54xmlpatterns qt54x11extras qt54websockets qt54sensors qt54script qt54quick1 qt54qbs qt54multimedia qt54location qt54imageformats qt54graphicaleffects qt54creator qt54connectivity

ppa 安装的 QT 位于 /opt/qt54,需要手动在 .bashrc 里添加来屏蔽系统 qt

1
2
## qt 5.4
source /opt/qt54/bin/qt54-env.sh

貌似加在 ~/.profile 会更好,登录就启用

SDL1.2

1
$ sudo apt-get install qtcreator qttools5-dev qtbase5-dev qt5-default qtdeclarative5-dev libqt5serialport5-dev libqt5svg5-dev libqt5webkit5-dev libsdl1.2-dev build-essential libudev-dev

定制编译

需要设置的编译选项可以创建并写在 user_config.pri 文件里,比如说关闭 qupgrade,设置 mavlink dialect 之类的。

1
2
DEFINES="DISABLE_QUPGRADE DISABLE_3DMOUSE"
MAVLINK_CONF="pixhawk"

额外功能

额外功能包括语音提示,3D flight view 之类的东西,参考官方指示安装

1
$ sudo apt-get install espeak libespeak-dev libopenscenegraph-dev

XBee

QGroundcontrol 内部包含了一个 xbee 的库,可以这样安装

1
2
3
$ cd libs/thirdParty/libxbee
$ make
$ sudo make install

编译

1
2
$ qmake
$ make

qmake 似乎执行一种 incremental build 的策略,据说不是很可靠,所以必要的时候需要先删除 build_release

生产

RC 信号由 src/drivers/px4io/px4io.cpp#L1653 发布,频率上限只有 50Hz (由 IO_POLL_INTERVAL 限制)。

事实上在同一块代码里发现,对电调的 PWM 输出也是限制在 50Hz。

发布载体为 struct rc_input_valuessensors.cpprc_poll() 流程如下:

  1. 发布流程图表明,无论信号质量怎样, rc_channels 总是会广播。本信息放的是归一化后的各通道数值,限制在 -1~1

    根据 rc_channels 的处理方式,油门的 trim 设置非常重要,一定等于该通道的最小值

  2. 如果信号质量正常,还会广播以 struct manual_control_setpoints_s 为载体的 manual_control_setpoint

    在 manual 控制模式下,本消息会复制到 _v_att_sp 供姿态控制 app 使用

  3. 最后,manual_control_setpoint 会复制到 actuator_controls_3,至于怎么用,需要进一步研究

内部消费

mavlink 模块会发送两种 RC 包,分别为 RC_CHANNELS_RAWRC_CHANNELS

RC_CHANNELS_RAW

RC_CHANNELS_RAW 是为了兼容老的飞控搞的一个消息。生成机制如下:

  • 首先,消息载体 mavlink_rc_channels_raw_t 只能装 8 路信号,然后一位 port 指示这 8 路走哪个端口。事实上好的遥控器很容易就超过 8 路,比如说有 18 路的 Futaba,那么这个载体肯定是不够用的。在这种情况下,port 可以复用来指示是低 8 路,中 8 路或者高 8 路;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef struct __mavlink_rc_channels_raw_t
    {
    uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot)
    uint16_t chan1_raw; ///< RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan2_raw; ///< RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan3_raw; ///< RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan4_raw; ///< RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan5_raw; ///< RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan6_raw; ///< RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan7_raw; ///< RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan8_raw; ///< RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint8_t port; ///< Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos.
    uint8_t rssi; ///< Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown.
    } mavlink_rc_channels_raw_t;
  • 然后,在 uORB 上实际在走的 rc 载体是 struct rc_input_values,除去 18 路信号外,还包含时间戳,丢包统计之类的东西,参见 drv_rc_input.h#90L;

  • mavlink 发送 RC 包的时候,会循环 3 次,发送 MAVLINK_MSG_ID_RC_CHANNELS_RAW 信息(因为一次只能发 8 路。。。)

RC_CHANNELS

RC_CHANNELS_RAW 消息发送以后,mavlink 会紧跟上发送 RC_CHANNELSRC_CHANNELS 的载体是 mavlink_rc_channels_t,跟 struct rc_input_values 相比,主要是少了丢包信息。

优化

简单地说,RC_CHANNELS_RAW 基本不会用到,发送频率又跟 RC_CHANNELS 绑定,最好的方法是直接注释掉。

基本命令

1
2
3
4
5
git config --global user.name ziyangli
git config --global user.email ziyang.d.lee@gmail.com

git config --list #查看配置的信息
git help push/config/*** # 查看某条命令的使用方式

新建仓库

1
2
git remote add origin git@github.com:***/test.git # 添加源
git push -u origin master # push 新建仓库到 origin 源,同时设置默认 up-stream 分支为 master

建立 fork 与上游版本的同步

显示目前项目的上游路径都有哪些,自己的一般是 origin 打头

1
$ git remote -v

添加上游路径

1
$ git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git

下载上游版本

1
$ git fetch upstream

Merge the changes from upstream/master into your local master branch

1
$ git merge upstream/master

解决本地修改与上游的冲突

资源

Lorenz 最近重新整理了一下 wiki,非常值得一个一个页面浏览一遍。

工具链安装

主要是安装依赖并将用户加入 dialout 组及 plugdev

1
2
$ sudo usermod -a -G dialout $USER
$ sudo usermod -a -G plugdev $USER

然后安装 arm-gcc,注意网上可以找到一个 ppa,但是不要使用,因为版本不对。

1
2
3
4
5
6
7
8
9
10
$ sudo apt-get install ia32-libs python-serial python-argparse grep
$ sudo apt-get install flex bison libncurses5-dev autoconf texinfo build-essential libtool zlib1g-dev genromfs git wget
$ pushd .
$ cd ~
$ wget https://launchpadlibrarian.net/174121628/gcc-arm-none-eabi-4_7-2014q2-20140408-linux.tar.bz2
$ tar -jxf gcc-arm-none-eabi-4_7-2014q2-20140408-linux.tar.bz2
$ exportline="export PATH=$HOME/gcc-arm-none-eabi-4_7-2014q2/bin:\$PATH"
$ if grep -Fxq "$exportline" ~/.profile; then echo nothing to do ; else echo $exportline >> ~/.profile; fi
$ . ~/.profile
$ popd

烧程序并上传固件

如果 NuttX 更新过

1
2
3
4
$ make distclean
$ make clean
$ make archives
$ make px4fmu-v2_default

否则

1
2
$ make clean
$ make px4fmu-v2_default

上传

1
$ make upload px4fmu-v2_default

经测试,这一步一定要先卸载 modemmanager

1
$ sudo apt-get remove modemmanager

系统启动

启动顺序由 /etc/init.d/rcS 控制,步骤:

  1. 检测硬件
  2. 加载传感器驱动
  3. 其他 apps

所有用于自动启动的脚本都位于 ROMFS/px4fmu_common/init.d/

  • 所以牛逼的人才自己写 etc/rc.txt,自己修改时改 etc/config.txtetc/extras.txt
  • 重刷固件的时候,SYS_AUTOCONFIG = 1,导致所有参数重置(包括这个变量)。
  • 重刷后依然想保留的配置(mixer, output mode, PWM range etc.),应该写在 etc/config.txt 里面。

The mavlink application sends and receives MAVLink packets on a serial port and translates them into the onboard object request broker structure.

app 功能

  • 航点管理 (waypoint management)
    1. 用户在地面站输入航点
    2. mavlink app 接收航点
    3. app 确定当前位置及当前激活航点的偏差判断是否到达
    4. 当前激活当点会作为位置控制器的输入
  • 参数更新 (updating of parameters)

使用

系统启动以后自动 TELEM1 (/dev/ttyS1) 开 mavlink。

  • 默认的波特率为 57600

如果希望用串口 (serial 4),需要自己手动启动或者加到启动脚本里。

1
nsh> mavlink start -d /dev/ttyS6 -b 460800

usb 口 (/dev/ttyACM0) 比较特殊,默认开的是一个 nsh,不发送 mavlink 信息。但是连上 QGC 以后,QGC 会通过 nsh 开 mavlink!

1
2
3
4
5
6
7
8
9
// https://github.com/mavlink/qgroundcontrol/blob/fc493d75c1e037e6d3919906c4b1a32ebe9cad91/src/comm/MAVLinkProtocol.cc#L189
// Send command to start MAVLink
// XXX hacky but safe
// Start NSH
const char init[] = {0x0d, 0x0d, 0x0d};
link->writeBytes(init, sizeof(init));
const char* cmd = "sh /etc/init.d/rc.usb\n";
link->writeBytes(cmd, strlen(cmd));
link->writeBytes(init, 4);

Mavlink 提供三种 log 功能。

1
2
3
mavlink_log_emergency(_fd, _str)
mavlink_log_critical(_fd, _str)
mavlink_log_info(_fd, _str)

这样子使用:

1
2
3
4
#include <mavlink/mavlink_log.h>
static int mavlink_fd;
mavlink_fd = open(MAVLINK_LOG_DEVICE, 0);
mavlink_log_info(mavlink_fd, "[myapp] Hello, this is myapp talking.");
  • MAVLINK_LOG_DEVICE = “/dev/mavlink”
    • 这个设备由 mavlink_main.cpp 注册,其它模块只打开及写入
  • mavlink_log.h 由 mavlink 提供,不是 Pixhawk 的一部分

其它

Output Mixers

The output mixer defines how the controller output gets mapped to the motor and servo outputs.

  1. 不同飞机的 mixer 都放在 etc/mixers,文件夹内有 README 可以看文件格式定义
  2. 个人定制的 mixer 文件命名为 FMU_ABC.mix,然后通过 MIXER = FMU_ABC 来使用

Custom Model

etc/config.txt 内可以定制机架类型。如果要定制 a quadcopter with “+” configuration with ESCs connected to PX4IO and custom PWM range (1100…1900),大概写成这样:

1
2
3
4
5
6
7
8
9
# Generic Quadcopter +
set VEHICLE_TYPE mc
set MIXER FMU_quad_+
# PX4IO PWM output will be used by default
set PWM_OUTPUTS 1234 # Change parameters for the first 4 outputs
set PWM_RATE 400 # Set PWM rate to 400 Hz for better performance
set PWM_DISARMED 900 # Motors should stop at this PWM value
set PWM_MIN 1100 # Motors should spin at low, idle speed at this PWM value
set PWM_MAX 1900 # Motors should spin at max speed at this PWM value

Circuit Breakers

断流器 (Circuit Breakers) 用来在软件上屏蔽某些模块。

例如想省去每次上电需要按 safety switch 的步骤,就可以使 CBRK_IO_SAFETY = 22027