PX4/Pixhawk---uORB深入理解和应用

The Instructions of uORB

『PX4/Pixhawk』 ? 『软件体系结构』?『uORB』?『主题发布』?『主题订阅』

1 简介

1.1 PX4/Pixhawk的软件体系结构

?PX4/Pixhawk的软件体系结构主要被分为四个层次,这可以让我们更好的理解PX4/Pixhawk的软件架构和运作:

  • 应用程序的API:这个接口提供给应用程序开发人员,此API旨在尽可能的精简、扁平及隐藏其复杂性。
  • 应用程序框架: 这是为操作基础飞行控制的默认程序集(节点)。
  • 库: 这一层包含了所有的系统库和基本交通控制的函数。
  • 操作系统: 最后一层提供硬件驱动程序,网络,UAVCAN和故障安全系统。

??uORB(Micro Object Request Broker,微对象请求代理器)是PX4/Pixhawk系统中非常重要且关键的一个模块,它肩负了整个系统的数据传输任务,所有的传感器数据、GPS、PPM信号等都要从芯片获取后通过uORB进行传输到各个模块进行计算处理。实际上uORB是一套跨「进程」 的IPC通讯模块。在Pixhawk中, 所有的功能被独立以进程模块为单位进行实现并工作。而进程间的数据交互就由为重要,必须要能够符合实时、有序的特点。

??Pixhawk使用的是NuttX实时ARM系统,uORB实际上是多个进程打开同一个设备文件,进程间通过此文件节点进行数据交互和共享。进程通过命名的「总线」交换的消息称之为「主题」(topic),在Pixhawk 中,一个主题仅包含一种消息类型,通俗点就是数据类型。每个进程可以「订阅」或者「发布」主题,可以存在多个发布者,或者一个进程可以订阅多个主题,但是一条总线上始终只有一条消息。

1.2 PX4/Pixhawk应用程序框架

??应用层中操作基础飞行的应用之间都是隔离的,这样提供了一种安保模式,以确保基础操作独立的高级别系统状态的稳定性。而沟通它们的就是uORB。

2 uORB文件夹说明

2.1 uORB文件夹结构

2.2 文件/目录说明

topics : 系统通用接口定义的标准主题,比如电池电量转态、GPS的位置参数等

module.mk : uORB模块makefile文件

objects_common.cpp: 通用接口标准主题定义集合,如添加新主题在这里定义

ORBMap.hpp : 对象请求器节点链表管理(驱动节点)

ORBSet.hpp : 对象请求器节点管理(非驱动节点)

Publication.cpp : 在不同的发布中遍历使用

Publication.hpp : 在不同的发布中遍历使用

Subscription.cpp : 在不同的订阅中遍历使用

Subscription.hpp : 在不同的订阅中遍历使用

uORB.cpp : uORB的实现

uORB.h : uORB头文件

uORBCommon.hpp : uORB公共部分变量定义实现

uORBCommunicator.hpp : 远程订阅的接口实现,实现了对不同的通信通道管理,如添加/移除订阅者,可以基于TCP/IP或fastRPC;传递给通信链路的实现,以提供在信道上接收消息的回调。

uORBDevices.hpp :

uORBDevices_nuttx.cpp : 节点操作,close,open,read,write

uORBDevices_nuttx.hpp :

uORBDevices_posix.cpp :

uORBDevices_posix.hpp :

uORBMain.cpp : uORB入口

uORBManager.hpp : uORB功能函数实现头文件

uORBManager_nuttx.cpp : uORB功能函数实现(Nuttx)

uORBManager_posix.cpp : uORB功能函数实现(Posix)

uORBTest_UnitTest.cpp : uORB测试

uORBTest_UnitTest.hpp : uORB测试头文件,包括主题定义和声明等

uORBUtiles.cpp :

uORBUtiles.hpp :

3 常用函数功能解析

int poll(struct pollfd fds[], nfds_t nfds, int timeout)

功能:监控文件描述符(多个);
说明:timemout=0,poll()函数立即返回而不阻塞;timeout=INFTIM(-1),poll()会一直阻塞下去,直到检测到return > 0;
参数:
    fds:struct pollfd结构类型的数组;
    nfds:用于标记数组fds中的结构体元素的总数量;
    timeout:是poll函数调用阻塞的时间,单位:毫秒;
返回值:
    >0:数组fds中准备好读、写或出错状态的那些socket描述符的总数量;
    ==0:poll()函数会阻塞timeout所指定的毫秒时间长度之后返回;
    -1:poll函数调用失败;同时会自动设置全局变量errno;

int orb_subscribe(const struct orb_metadata *meta)

功能:订阅主题(topic);
说明:即使订阅的主题没有被公告,但是也能订阅成功;但是在这种情况下,却得不到数据,直到主题被公告;
参数:
    meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
返回值:
    错误则返回ERROR;成功则返回一个可以读取数据、更新话题的句柄;如果待订阅的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
eg:
    int fd = orb_subscribe(ORB_ID(topicName));

int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)

功能:从订阅的主题中获取数据并将数据保存到buffer中;
参数:
    meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
    handle:订阅主题返回的句柄;
    buffer:从主题中获取的数据;
返回值:
    返回OK表示获取数据成功,错误返回ERROR;否则则有根据的去设置errno;
eg:
    struct sensor_combined_s raw;
    orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);

orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data)

功能:公告发布者的主题;
说明:在发布主题之前是必须的;否则订阅者虽然能订阅,但是得不到数据;
参数:
    meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
    data:指向一个已被初始化,发布者要发布的数据存储变量的指针;
返回值:错误则返回ERROR;成功则返回一个可以发布主题的句柄;如果待发布的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
eg:
    struct vehicle_attitude_s att;
    memset(&att, 0, sizeof(att));
    int att_pub_fd = orb_advertise(ORB_ID(vehicle_attitude), &att);

int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)

功能:发布新数据到主题;
参数:
    meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
    handle:orb_advertise函数返回的句柄;
    data:指向待发布数据的指针;
返回值:OK表示成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
    orb_publish(ORB_ID(vehicle_attitude), att_pub_fd, &att);

int orb_set_interval(int handle, unsigned interval)

功能:设置订阅的最小时间间隔;
说明:如果设置了,则在这间隔内发布的数据将订阅不到;需要注意的是,设置后,第一次的数据订阅还是由起初设置的频率来获取,
参数:
    handle:orb_subscribe函数返回的句柄;
    interval:间隔时间,单位ms;
返回值:OK表示成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
    orb_set_interval(sensor_sub_fd, 1000);

orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority)

功能:设备/驱动器的多个实例实现公告,利用此函数可以注册多个类似的驱动程序;
说明:例如在飞行器中有多个相同的传感器,那他们的数据类型则类似,不必要注册几个不同的话题;
参数:
    meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
    data:指向一个已被初始化,发布者要发布的数据存储变量的指针;
    instance:整型指针,指向实例的ID(从0开始);
    priority:实例的优先级。如果用户订阅多个实例,优先级的设定可以使用户使用优先级高的最优数据源;
返回值:
    错误则返回ERROR;成功则返回一个可以发布主题的句柄;如果待发布的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
eg:
    struct orb_test t;
    t.val = 0;
    int instance0;
    orb_advert_t pfd0 = orb_advertise_multi(ORB_ID(orb_multitest), &t, &instance0, ORB_PRIO_MAX);

int orb_subscribe_multi(const struct orb_metadata *meta, unsigned instance)

功能:订阅主题(topic);
说明:通过实例的ID索引来确定是主题的哪个实例;
参数:
    meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
    instance:主题实例ID;实例ID=0与orb_subscribe()实现相同;
返回值:
    错误则返回ERROR;成功则返回一个可以读取数据、更新话题的句柄;如果待订阅的主题没有定义或声明则会返回-1,然后会将errno赋值为ENOENT;
eg:
    int sfd1 = orb_subscribe_multi(ORB_ID(orb_multitest), 1);

int orb_unsubscribe(int handle)

功能:取消订阅主题;
参数:
    handle:主题句柄;
返回值:
    OK表示成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
    ret = orb_unsubscribe(handle);

int orb_check(int handle, bool *updated)

功能:订阅者可以用来检查一个主题在发布者上一次更新数据后,有没有订阅者调用过ob_copy来接收、处理过;
说明:如果主题在在被公告前就有人订阅,那么这个API将返回“not-updated”直到主题被公告。可以不用poll,只用这个函数实现数据的获取。
参数:
    handle:主题句柄;
    updated:如果当最后一次更新的数据被获取了,检测到并设置updated为ture;
返回值:
    OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
    if (PX4_OK != orb_check(sfd, &updated)) {
        return printf("check(1) failed");
    }
    if (updated) {
        return printf("spurious updated flag");
    }

    //or

    bool updated;
    struct random_integer_data rd;

    /* check to see whether the topic has updated since the last time we read it */
    orb_check(topic_handle, &updated);

    if (updated) {
        /* make a local copy of the updated data structure */
        orb_copy(ORB_ID(random_integer), topic_handle, &rd);
        printf("Random integer is now %d\n", rd.r);
    }

int orb_stat(int handle, uint64_t *time)

功能:订阅者可以用来检查一个主题最后的发布时间;
参数:
    handle:主题句柄;
    time:存放主题最后发布的时间;0表示该主题没有发布或公告;
返回值:
    OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
    ret = orb_stat(handle,time);

int orb_exists(const struct orb_metadata *meta, int instance)

功能:检测一个主题是否存在;
参数:
    meta:uORB元对象,可以认为是主题id,一般是通过ORB_ID(主题名)来赋值;
    instance:ORB 实例ID;
返回值:
    OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
    ret = orb_exists(ORB_ID(vehicle_attitude),0);

int orb_priority(int handle, int *priority)

功能:获取主题优先级别;
参数:
    handle:主题句柄;
    priority:存放获取的优先级别;
返回值:
    OK表示检测成功;错误返回ERROR;否则则有根据的去设置errno;
eg:
    ret = orb_priority(handle,&priority);

4 例程

4.1 例程前准备工作
  • archives已编译完成;
  • 添加一个新的模块
    • 在Firmware/src/modules中添加一个新的文件夹,命名为px4_simple_app
    • 在px4_simple_app文件夹中创建module.mk文件,并输入以下内容:
      • MODULE_COMMAND = px4_simple_app
      • SRCS = px4_simple_app.c
    • 在px4_simple_app文件夹中创建px4_simple_app.c文件
/**
 * @file px4_simple_app.c
 * Minimal application example for PX4 autopilot.
 */

#include <nuttx/config.h>
#include <stdio.h>
#include <errno.h>

__EXPORT int px4_simple_app_main(int argc, char *argv[]);

int px4_simple_app_main(int argc, char *argv[])
{
    printf("Hello Sky!\n");
    return OK;
}
  • 注册新添加的应用到NuttShell中,并编译上传

    • Firmware/makefiles/config_px4fmu-v2_default.mk文件中添加如下内容:

      • MODULES += modules/px4_simple_app
    • 编译
      • make clean
      • make px4fmu-v2_default
    • 上传到板子中
      • make upload px4fmu-v2_default
  • 在QGC 中的Terminal(终端)中运行新应用
    • nsh > px4_simple_app

?接下来的代码修改均是基于此应用。

4.2 订阅主题

?sensor_combined主题是官方提供的通用接口标准主题。

/**
 * @file px4_simple_app.c
 * Minimal application example for PX4 autopilot
 */

#include <nuttx/config.h>
#include <unistd.h>
#include <stdio.h>
#include <poll.h>

#include <uORB/uORB.h>
#include <uORB/topics/sensor_combined.h>

__EXPORT int px4_simple_app_main(int argc, char *argv[]);

int px4_simple_app_main(int argc, char *argv[])
{
    printf("Hello Sky!\n");

    /*订阅sensor_combined 主题*/
    int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));

     /*一个应用可以等待多个主题,在这里只等待一个主题*/
    struct pollfd fds[] = {
        { .fd = sensor_sub_fd,   .events = POLLIN },
        /* 这里可以添加更多的文件描述符;
         * { .fd = other_sub_fd,   .events = POLLIN },
         */
    };

    int error_counter = 0;

    while (true) {
        /*poll函数调用阻塞的时间为1s*/
        int poll_ret = poll(fds, 1, 1000);

        /*处理poll返回的结果 */
        if (poll_ret == 0) {
            /* 这表示时间溢出了,在1s内没有获取到发布者的数据 */
            printf("[px4_simple_app] Got no data within a second\n");
        } else if (poll_ret < 0) {
            /* 出现问题 */
            if (error_counter < 10 || error_counter % 50 == 0) {
                /* use a counter to prevent flooding (and slowing us down) */
                printf("[px4_simple_app] ERROR return value from poll(): %d\n"
                    , poll_ret);
            }
            error_counter++;
        } else {

            if (fds[0].revents & POLLIN) {
                /*从文件描述符中获取订阅的数据*/
                struct sensor_combined_s raw;
                /* copy sensors raw data into local buffer */
                orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
                printf("[px4_simple_app] Accelerometer:\t%8.4f\t%8.4f\t%8.4f\n",
                    (double)raw.accelerometer_m_s2[0],
                    (double)raw.accelerometer_m_s2[1],
                    (double)raw.accelerometer_m_s2[2]);
            }
            /* 如果有更多的文件描述符,可以这样:
             * if (fds[1..n].revents & POLLIN) {}
             */
        }
    }

    return 0;
}
测试需要在QGC终端启动uORB和初始化该传感器,最后运行应用:
    nsh > uorb start
    nsh > sh /etc/init.d/rc.sensors
    nsh > px4_simple_app &
4.3 订阅和发布主题

?sensor_combined主题是官方提供的通用接口标准主题。

?vehicle_attitude主题是官方提供的通用接口标准主题。

?程序流程图如下:

/**
 * @file px4_simple_app.c
 * Minimal application example for PX4 autopilot
 */

#include <nuttx/config.h>
#include <unistd.h>
#include <stdio.h>
#include <poll.h>

#include <uORB/uORB.h>
#include <uORB/topics/sensor_combined.h>
#include <uORB/topics/vehicle_attitude.h>

__EXPORT int px4_simple_app_main(int argc, char *argv[]);

int px4_simple_app_main(int argc, char *argv[])
{
    printf("Hello Sky!\n");

    /* 订阅 sensor_combined 主题 */
    int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));
    orb_set_interval(sensor_sub_fd, 1000);

    /* 公告 attitude 主题 */
    struct vehicle_attitude_s att;
    memset(&att, 0, sizeof(att));
    int att_pub_fd = orb_advertise(ORB_ID(vehicle_attitude), &att);

    /*一个应用可以等待多个主题,在这里只等待一个主题*/
    struct pollfd fds[] = {
        { .fd = sensor_sub_fd,   .events = POLLIN },
        /* there could be more file descriptors here, in the form like:
         * { .fd = other_sub_fd,   .events = POLLIN },
         */
    };

    int error_counter = 0;

    while (true) {
        /* wait for sensor update of 1 file descriptor for 1000 ms (1 second) */
        int poll_ret = poll(fds, 1, 1000);

        /* handle the poll result */
        if (poll_ret == 0) {
            /* this means none of our providers is giving us data */
            printf("[px4_simple_app] Got no data within a second\n");
        } else if (poll_ret < 0) {
            /* this is seriously bad - should be an emergency */
            if (error_counter < 10 || error_counter % 50 == 0) {
                /* use a counter to prevent flooding (and slowing us down) */
                printf("[px4_simple_app] ERROR return value from poll(): %d\n"
                    , poll_ret);
            }
            error_counter++;
        } else {

            if (fds[0].revents & POLLIN) {
                /* obtained data for the first file descriptor */
                struct sensor_combined_s raw;
                /* copy sensors raw data into local buffer */
                orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
                printf("[px4_simple_app] Accelerometer:\t%8.4f\t%8.4f\t%8.4f\n",
                    (double)raw.accelerometer_m_s2[0],
                    (double)raw.accelerometer_m_s2[1],
                    (double)raw.accelerometer_m_s2[2]);

                /* 赋值 att 并且发布这些数据给其他的应用 */
                att.roll = raw.accelerometer_m_s2[0];
                att.pitch = raw.accelerometer_m_s2[1];
                att.yaw = raw.accelerometer_m_s2[2];
                orb_publish(ORB_ID(vehicle_attitude), att_pub_fd, &att);
            }
            /* there could be more file descriptors here, in the form like:
             * if (fds[1..n].revents & POLLIN) {}
             */
        }
    }

    return 0;
}
4.4 创建自己的主题

??官方提供的通用接口标准主题都放在了topics文件夹下了。如果要定义我们自己的主题,比如我们新添加了超声波传感器,为了将超声波传感器的数据发布出去给其他需要的应用订阅,那么久需要创建我们的主题了。

  • 主题头文件(mytopic.h)

    • ORB_DECLARE(myTopicName);//声明一个主题
    • 定义一个存放发布数据的结构体;
  • 主题源文件(mytopic.c)
    • ORB_DEFINE(myTopicName);//定义一个主题
    • 初始化发布数据
    • 公告主题
    • 发布主题数据

mytopic.h

/* 声明自定义主题,名字可以自定义,不过最好具有一定的意义,如下为随机产生整数数据 */
ORB_DECLARE(random_integer);

/* 定义要发布的数据结构体 */
struct random_integer_data {
    int r;
};

mytopic_publish.c

#include <topic.h>

/* 定义主题 */
ORB_DEFINE(random_integer);

/* 待发布的主题句柄 */
static int topic_handle;

int init()
{
    /* 随机产生一个数初始化数据结构体 */
    struct random_integer_data rd = { .r = random(), };

    /* 公告主题 */
    topic_handle = orb_advertise(ORB_ID(random_integer), &rd);
}

int update_topic()
{
    /* 产生新的数据 */
    struct random_integer_data rd = { .r = random(), };

    /* 发布主题,更新数据 */
    orb_publish(ORB_ID(random_integer), topic_handle, &rd);
}

??对于订阅者来说,就可以参考主题「4.2 订阅例程」了。不过这里还是提供下简单处理例程:

mytopic_subscriber.c

#include <topic.h>

/* 订阅主题的句柄*/
static int topic_handle;

int init()
{
    /* 订阅主题 */
    topic_handle = orb_subscribe(ORB_ID(random_integer));
}

void check_topic()
{
    bool updated;
    struct random_integer_data rd;

    /* check to see whether the topic has updated since the last time we read it */
    orb_check(topic_handle, &updated);

    if (updated) {
        /* make a local copy of the updated data structure */
        orb_copy(ORB_ID(random_integer), topic_handle, &rd);
        printf("Random integer is now %d\n", rd.r);
    }
}

5 参考资料

??http://www.pixhawk.com/start?id=zh/dev/px4_simple_app

??http://www.pixhawk.com/dev/shared_object_communication

??http://blog.arm.so/armteg/pixhawk/183-0503.html

??http://pixhawk.org/start?id=dev/software_architecture

??http://www.pixhawk.com/dev/add_uorb_topic?s[]=objects&s[]=common

版权声明:本文为博主"原创"文章,未经博主允许可以转载。

时间: 2024-08-09 22:01:48

PX4/Pixhawk---uORB深入理解和应用的相关文章

px4固定翼无人机姿态控制理解

学习px4代码也有一段时间了,所以想写一写,自己的一些学习心得吧,也算是笔记吧. 在px4这套代码中,每一个功能都是一个模块,例如姿态控制,也就是一个应用程序,我们可以把它添加到初始话脚本里,让它自启动.需要注意的就是在一个应用程序就是处理订阅的消息,然后发布处理过后的消息.这种消息机制就是uorb消息机制,可以找资料学习它具体实现的一个过程. 接下来,就逐步学习一下这个姿态控制的模块. 首先就是应用程序的入口,"extern "C" __EXPORT int fw_att_

PX4/Pixhawk---基于NSH调试的uORB第一个应用测试

PX4/Pixhawk-基于NSH调试的uORB第一个应用测试 1 NSH连接测试 ??(1) 测试前准备: PX4FMU(已刷好固件) USB线 安装好PX4 Toolchain ??(2) Pixhawk通过USB连接电脑,并安装好了驱动: ?? ??(3) 打开Tera Term软件(PX4 Toolchain->TeraTerm): ?? 2 开始第一个应用 ??http://www.pixhawk.com/start?id=zh/dev/px4_simple_app 版权声明:本文为博

转载:Pixhawk源码笔记四:学习RC Input and Output

转自:新浪@WalkAnt 第五部分 学习RC Input and Output 参考:http://dev.ardupilot.com/wiki/learning-ardupilot-rc-input-output/ RC Input,也就是遥控输入,用于控制飞行方向.改变飞行模式.控制摄像头等外围装置.ArduPilot支持集中不同RC input(取决于具体的硬件飞控板): 1. PPMSum – on PX4, Pixhawk, Linux and APM2 2. SBUS – on P

无人机开发之一:Pixhawk与Arduino简述

1. Pixhawk发展历史 发展历程:APM-->PX4FMU/IO-->Pixhawk: 1.1. Arduino简介 Arduino就是主要以以AVR单片机为核心控制器的单片机应用开发板(当然也有其他核心的例如STM32版本的但是不是官方的,还有intel的伽利略),或者是学习板啥的,Arduino开发人员开发了简单的函数,还有许多应用库,这样就不用直接去操作寄存器了,使得没有很好的单片机基础的人员也可以使用Arduino做出自己想要的东西.Arduino的开发人员还开发了一个简洁的ID

无人机--飞控科普

无人机是无人驾驶飞机的简称(Unmanned Aerial Vehicle,UAV),是利用无线电遥控设备和自备的程序控制装置的不载人飞机,包括无人直升机.固定翼机.多旋翼飞行器.无人飞艇.无人伞翼机.广义地看也包括临近空间飞行器(20-100 公里空域),如平流层飞艇.高空气球.太阳能无人机等.从某种角度来看,无人机可以在无人驾驶的条件下完成复杂空中飞行任务和各种负载任务,可以被看做是“空中机器人”. 飞控系统是无人机完成起飞.空中飞行.执行任务和返场回收等整个飞行过程的核心系统,飞控对于无人

2016.2.15 四旋翼相关资料

--------2016.2.15--------最近在玩儿四旋翼,所以相关的资料我会贴上来供需要的朋友参考,如果遇到了我们趟过的地雷就能够方便一些. 机架:F450我们之后由于要将NVIDIA的开发板和飞行器连在一起,所以从机架的选择上我们要慎重考虑,之前为了方便选的是F330,但是DJI正版的F330停产了,所以taobao的F330进行测试,经过测试发现F330相当脆弱,机架非常容易在后写撞击中折断,所以如果上面搭载NVIDIA的开发板的话,那么这样开发的成本太高,一旦炸机可能机毁板子亡,

在linux使用make编译ArduPilot for Pixhawk/PX4 ArduPilot 编译环境搭建

Building ArduPilot for Pixhawk/PX4 on Linux with Make 使用Make编译 ArduPilot for Pixhawk 2, Pixhawk and PX4 在linux上. Note: 编译 Pixhawk 2 and Pixhawk使用 (make px4-v2). 编译 PX4 使用 make px4-v1. Quick start 系统ubuntu16.04 Setup 安装 git: sudo apt-get -qq -y instal

[pixhawk笔记]11-Windows下PX4代码查看

由于项目需要做基于Simulink的PX4二次开发,在Windows下面做,所以需要在Windows下查看PX4的代码,故写该文档,记录环境安装和配置过程.按照该网页安装工具链:Windows Installation Instructions. 安装后用工具链中的eclipse查看代码,由于只是在windows下面查看代码,而固件开发还是在ubuntu下面做,所以只安装工具链,不安装驱动也可以.笔者的系统是win10 64位,但是安装了工具链之后,发现安装eclipse打开会报java运行环境

Pixhawk之姿态控制篇(1)_源码算法分析(超级有料)

一.开篇 姿态控制篇终于来了.来了.来了~~~ 心情爽不爽?愉悦不愉悦?开心不开心? 喜欢的话就请我吃顿饭吧,哈哈. 其实这篇blog一周前就应该写的,可惜被上一篇blog霸占了.但是也不算晚,整理了很多算法基础知识,使得本篇blog更充实.一人之力总是有限的,难免有不足之处,大家见谅,有写的不好的地方劳烦指正.看到标题了吧,属于连载篇,所以后续还会有相关问题的补充的. 二.版权声明 博主:summer 声明:喝水不忘挖井人,转载请注明出处. 原文地址:http://blog.csdn.net/