大疆社区

标题: 【OSDK】读OSDK起飞降落控制代码 [打印本页]

作者: 懒猫吃鱼    时间: 2020-12-4
标题: 【OSDK】读OSDK起飞降落控制代码
接触DJI Onboard SDK有了一段时间,单纯靠官方的文档来玩SDK也许会有一定的难度,在配合文档的条件下仔细查看代码也许玩SDK会更方便,毕竟SDK是以代码(源码或库)方式提供出来的。
简单记录一下DJI Onboard SDK提供的基础功能sample代码,通过sample来了解OSDK提供的功能,了解SDK之后再来实现自己想要的功能。

本文先记录一下飞行控制功能sample:djiosdk-flightcontrol-sample,本文以官方发布版本4.0.1来记录,大致查看了下master分支版本,貌似又有了变更,大致猜测基本功能应该一样,具体差异后续发现再更新。
OSDK的飞行控制功能是一个基本控制功能,用于DJI无人机脱离遥控器的控制(严谨一点,M210和M300系列起飞会检测遥控器连接,未连接遥控器起飞会有飞行距离限制),通过机载计算机程序来实现飞机的自动飞行,
本人习惯玩Linux环境,先记录记录Linux环境下的使用,STM32平台和ROS平台差别应该不大,在API层功能应该是一致的。
首先先找个main,文件夹路径:
/Onboard-SDK-4.0.1/sample/platform/linux/flight-control/main.cpp

这篇文章已经很冗余了,不逐行跟代码,主要记录一下基本流程以及API调用,或许能贡献一点查代码的思维或思路。
大体上看flight control代码逻辑:
main.cpp
        1、配置OSDK运行环境
        2、获取控制权
        3、飞行控制demo
                option    功能
                   a      起飞    ----->    降落
                   b      起飞    ----->    位置偏移飞行(位置1,2,3)   --------> 降落
                   c      起飞    ----->    位置偏移飞行(位置1,2)  ------>   设置新的home点  ------>  设置返航点的高度   ------>  避障设置  -----> 返航降落
                  
flight_control_sample.hpp        
flight_control_sample.cpp
    main中a,b选项功能具体功能的实现

flight_sample.hpp
flight_sample.cpp
        main中c选项功能具体功能的实现
        
这个代码结构描述比较将就,查代码结构还是建议按照官方提供的源码结构去厘清,这里主要目的是方便通过demo来索引出OSDK的API调用和功能使用。
比如b选项和c选项功能实现并不在同一个文件(或者称暂且为类吧)中,看代码描述还有机型的限制, 这两部分虽说都是同一功能类实现上看起来差别还是有点大。

继续往下追代码,a,b功能均在flight_control_sample.hpp中实现,通过上面介绍总结来说,a, b功能就是起飞,降落,定点飞。
起飞和降落:
/*! Monitored Takeoff
    This implementation of takeoff  with monitoring makes sure your aircraft
    actually took off and only returns when takeoff is complete.
    Use unless you want to do other stuff during takeoff - this will block
    the main thread.
!*/
bool monitoredTakeoff(DJI::OSDK::Vehicle* vehiclePtr, int timeout = 1);

/*! Monitored Landing (Blocking API call). Return status as well as ack.
    This version of takeoff makes sure your aircraft actually took off
    and only returns when takeoff is complete.

!*/
bool monitoredLanding(DJI::OSDK::Vehicle* vehiclePtr, int timeout = 1);

定点飞:
/*! Position Control. Allows you to set an offset from your current
    location. The aircraft will move to that position and stay there.
    Typical use would be as a building block in an outer loop that does not
    require many fast changes, perhaps a few-waypoint trajectory. For smoother
    transition and response you should convert your trajectory to attitude
    setpoints and use attitude control or convert to velocity setpoints
    and use velocity control.
!*/
bool
moveByPositionOffset(Vehicle *vehicle, float xOffsetDesired,
                     float yOffsetDesired, float zOffsetDesired,
                     float yawDesired, float posThresholdInM,
                     float yawThresholdInDeg)

附上API说明,毕竟这是DJI SDK API开发大牛给出的设计信息,可以帮助我们理解代码。这个封装的功能代码涉及信息较多,我这里先查有用的信息,再看实现细节。浏览函数实现调用:
  // Start takeoff
  ACK::ErrorCode takeoffStatus = vehicle->control->takeoff(timeout);

这个API似乎有点来头,因为通过这个调用可以索引到SDK底层的API, 查看API文件:
dji_control.hpp
dji_control.cpp

再看看文件在文件夹中的位置:Onboard-SDK-master\osdk-core\api\inc,代码文件基本已经串通了。

再看看这个API的实现代码:
ACK::ErrorCode
Control::takeoff(int wait_timeout)
{
  if (vehicle->isLegacyM600())
  {
    return this->action(FlightCommand:: LegacyCMD::takeOff, wait_timeout);
  }
  else if (vehicle->isM100())
  {
    return this->action(FlightCommand:: LegacyCMD::takeOff, wait_timeout);
  }
  else
  {
    return this->action(FlightCommand:: takeOff, wait_timeout);
  }
}

到这个地方可以暂时缓一缓,理解一下。当然这部分还可以继续追代码,因为已经可以看到定义的takeoff指令,而且实现中可以看到指令定义与机型是有关的,所以可以比较清晰的看到OSDK控制起飞的操作。不同机型控制指令还有点点不一样。

这个API很简单,理解一下:
API已经找到,再看一下我们传给飞机的参数(同步API为例),takeoff指令之外,就是timeout参数。我们可以确认到OSDK的起飞控制,实际就是发送了一个起飞指令。

指令API很简单,我们再回溯一下代码,那就回到了官方提供的sample函数:monitoredTakeoff,代码就不贴出来了,monitoredTakeoff函数放在sample文件中,提供的是对应API调用的范例和封装,还是值得花时间看看的。
        大致看下函数的实现:
        1、遥测数据订阅,TOPIC_STATUS_FLIGHT,TOPIC_STATUS_DISPLAYMODE
        2、发送起飞指令
        3、检查起飞状态
        
    根据实现总结一下,调用SDK的API去发送takeoff指令,通过订阅数据获取飞机状态判断起飞是否成功。也就是发送takeoff为瞬间的指令,但是飞机是否成功起飞是个动态的过程,这个函数就是封装了一层由发送指令到监控起飞过程
        的一个功能。
               
        遥测数据订阅,在OSDK中是单独的一个功能,这暂不介绍了。有空继续更新遥测数据及订阅功能部分相关,先看看这里使用到的两个TOPIC:TOPIC_STATUS_FLIGHT和TOPIC_STATUS_DISPLAYMODE
        可以通过官网API介绍,其实也可以直接查代码。查看到这两个TOPIC的数据及意义,两个TOPIC获取的数据在代码中均为飞机状态,为enum类型,尽管文档不是很友好,还是可以猜一猜的。
        定义文件:dji_status.hpp
        namespace FlightStatus
        {
        enum
        {
          STOPED      = 0,
          ON_GROUND   = 1,
          IN_AIR      = 2
        };
        } // namespace FlightStatus
        
        DisplayMode太多了,就不贴了。
        判断起飞状态的组合就是通过这两个状态回馈获取并判断,这部分代码了解这个基本也就理解了。

另外landing部分与takeoff基本一致,就不赘述了。        moveByPositionOffset这个定点飞本想在这一起写写,这个API包括SDK底层的API都会较为复杂一点,暂不在这里写了,有空再找个时间再补充补充。


作者: 大皮    时间: 2021-1-21
我想问下A3飞控能使用OSDK3.9和遥控器一同控制吗,我现在使用的是STM32,现在出现一个问题,就是我使用遥控器控制的话,OSDK就发控制命令就控制不了,使用OSDK控制,遥控器就控制不了,这是什么原因呢
作者: kv886    时间: 2021-1-21
大皮1-21 18:23
我想问下A3飞控能使用OSDK3.9和遥控器一同控制吗,我现在使用的是STM32,现在出现一个问题,就是我使用遥控器控制的话,OSDK就发控制命令就控制不了,使用OSDK控制,遥控器就控制不了,这是什么原因呢
正常,就是这么设计的,只有一个设备能控制。哪个设备有控制权,哪个设备就能控制
作者: 大皮    时间: 2021-1-27
kv8861-21 19:20
正常,就是这么设计的,只有一个设备能控制。哪个设备有控制权,哪个设备就能控制
好的,谢谢
作者: fans7faa295d    时间: 2021-4-15
老师,您好,请问OSDK支持在执行前一个命令的过程中中断进行下一个命令,比如在执行由四个航点构成的航线的过程中,在无人机往第三个航点飞行前进的时候,可以发送一个命令使无人机返航或降落吗




欢迎光临 大疆社区 (https://bbs.dji.com/) Powered by Discuz! X3.2