Kerloud 飞车在线控制C++教程
Kerloud 飞车在线控制C++教程
- 产品简介
- 基于ROS C++ API的Offboard控制
- (1)环境设置
- (2)代码讲解
- 订阅、发布、服务的声明
- 服务指令构建
- 陆地车、多旋翼模式下的航路点坐标解析
- 模式切换
- 如何进行实测
- 如何购买
产品简介
Kerloud flying rover是由云讷科技(深圳)有限公司推出的一款面向飞车爱好者的高性价比开发平台,产品设计紧凑,兼具无人机(UAV)、无人车(UGV)模式。平台支持辅助模块扩展(树莓派、英伟达电脑),基于云讷官方提供的开源C++、Python版本SDK,用户可在室内、室外场景下快捷展开应用开发。
本教程完整链接为:https://cloudkerneltech.gitbook.io/kerloud-flyingrover/user-guide-zh/tutorials_zh/offboard_cplus
更多信息请参考官方产品网页:https://cloudkerneltech.gitbook.io/kerloud-flyingrover/
基于ROS C++ API的Offboard控制
本教程将演示如何控制飞车在陆地车、多旋翼模式下实现航路点任务。
(1)环境设置
本教程推荐的环境为Ubuntu18.04系统下ROS melodic。
现成可用的ROS工作区位于机载电脑~/src/catkinws_offboard目录下,该工作区包含我们官方资源库中的软件包,官方在维护的资源库链接如下:
- mavros: https://github.com/cloudkernel-tech/mavros
- mavlink: https://github.com/cloudkernel-tech/mavlink-gdp-release
- offboard control node: https://github.com/cloudkernel-tech/offboard_flyingrover
用户可通过如下指令更新到最新版本:
cd ~/src/catkinws_offboard/mavros
git pull origin
git checkout dev_flyingrovercd ~/src/catkinws_offboard/mavlink
git pull origin
git checkout dev_flyingrovercd ~/src/catkinws_offboard/offboard_flyingrover
git pull origin
git checkout dev_flyingrover
编译工作区:
cd ~/src/catkinws_offboard
catkin build -j 1 # set j=1 only for raspberry Pi
在树莓派电脑上,此编译过程耗时可能超过十分钟,首次操作时请耐心等待。
可使用如下指令清空工作区:
cd ~/src/catkinws_offboard
catkin clean
(2)代码讲解
例程代码为标准ROS节点形式,用户需熟悉官方ROS教程中发布、订阅节点的编程方法,官方链接为:http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber(c%2B%2B)。 重点指出,offboard_flyingrover节点包含以下几个文件:
- offboard_flyingrover/launch/off_mission.launch: offboard控制节点的默认启动文件。
- offboard_flyingrover/launch/waypoints_xyzy.yaml: ENU坐标系下的航路点任务定义文件,包含相应的偏航信息。
- offboard_flyingrover/src/off_mission_node.cpp: 用于offboard控制的ROS节点文件。
本例程实现的任务描述如下:飞车将先在陆地车模式下走过几个航路点,到达最后一个航路点后切换为多旋翼模式,然后起飞依次走过之前相同的航路点。为清晰起见,我们在此按顺序讲解off_mission_node中的主要功能:
订阅、发布、服务的声明
我们通常在主程序开头处声明ROS的订阅、发布、服务。
通过mavros包中丰富的主题或服务,可轻松实现信息获取或命令发送。例如,若要获取无人机的本地位置信息,则需订阅mavros/setpoint_position/local主题。请注意,所用坐标系为ENU(East-North-Up)。Mavros软件包的标准信息可参见:http://wiki.ros.org/mavros。对于飞车专用的其他主题或服务,请参阅API部分。
/*subscriptions, publications and services*/
ros::Subscriber state_sub = nh.subscribe<mavros_msgs::State>("mavros/state", 5, state_cb);//subscription for flying rover state
ros::Subscriber extended_state_sub = nh.subscribe<mavros_msgs::ExtendedState>("mavros/extended_state", 2, extendedstate_cb);//subscription for local position
ros::Subscriber local_pose_sub = nh.subscribe<geometry_msgs::PoseStamped>("mavros/local_position/pose", 5, local_pose_cb);ros::Subscriber rc_input_sub = nh.subscribe<mavros_msgs::RCIn>("mavros/rc/in", 5, rc_input_cb);//publication for local position setpoint
ros::Publisher local_pos_pub = nh.advertise<geometry_msgs::PoseStamped>("mavros/setpoint_position/local", 5);//service for arm/disarm
ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>("mavros/cmd/arming");//service for main mode setting
ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>("mavros/set_mode");//service for command send
ros::ServiceClient command_long_client = nh.serviceClient<mavros_msgs::CommandLong>("mavros/cmd/command");
服务指令构建
接下来,我们将通过如下方式创建必要的命令来调用上文中所定义的服务。
/*service commands*/
mavros_msgs::SetMode offb_set_mode;
offb_set_mode.request.custom_mode = "OFFBOARD";mavros_msgs::CommandBool arm_cmd;
arm_cmd.request.value = true;mavros_msgs::CommandBool disarm_cmd;
disarm_cmd.request.value = false;//flying rover mode switching commands
mavros_msgs::CommandLong switch_to_mc_cmd;//command to switch to multicopter
switch_to_mc_cmd.request.command = (uint16_t)mavlink::common::MAV_CMD::DO_FLYINGROVER_TRANSITION;
switch_to_mc_cmd.request.confirmation = 0;
switch_to_mc_cmd.request.param1 = (float)mavlink::common::MAV_FLYINGROVER_STATE::MC;mavros_msgs::CommandLong switch_to_rover_cmd;//command to switch to rover
switch_to_rover_cmd.request.command = (uint16_t)mavlink::common::MAV_CMD::DO_FLYINGROVER_TRANSITION;
switch_to_rover_cmd.request.confirmation = 0;
switch_to_rover_cmd.request.param1 = (float)mavlink::common::MAV_FLYINGROVER_STATE::ROVER;
陆地车、多旋翼模式下的航路点坐标解析
陆地车、多旋翼模式下的航路点坐标信息,会以不同的方式传递到位置设定主题。多旋翼模式下,需要用到3D位置,而且起飞过程需单独处理;陆地车模式下,则可直接将2D位置传递到所需的主题。
if (current_wpindex == 0){//use yaw measurement during multicopter takeoff (relative height<1) to avoid rotation, and use relative poseif (_flyingrover_mode == FLYINGROVER_MODE::MULTICOPTER){//initialize for the 1st waypoint when offboard is triggeredif (!is_tko_inited_flag && current_state.mode=="OFFBOARD"){//reload waypoint from yamlinitTagetVector(wp_list);waypoints.at(0).pose.position.x += current_local_pos.pose.position.x; //set with relative position herewaypoints.at(0).pose.position.y += current_local_pos.pose.position.y;waypoints.at(0).pose.position.z += current_local_pos.pose.position.z;tf::Quaternion q = tf::createQuaternionFromYaw(current_yaw);//set with current yaw measurementtf::quaternionTFToMsg(q, waypoints.at(0).pose.orientation);is_tko_inited_flag = true;}//update yaw setpoint after tko is finishedif (is_tko_inited_flag && !is_tko_finished){if (current_local_pos.pose.position.z >2.0f){ //reset yaw to wp_list valueROS_INFO("Takeoff finished, reset to waypoint yaw");XmlRpc::XmlRpcValue data_list(wp_list[0]);tf::Quaternion q = tf::createQuaternionFromYaw(data_list[3]);tf::quaternionTFToMsg(q, waypoints.at(0).pose.orientation);is_tko_finished = true;}}}else //rover mode, pass relative update, use loaded waypoints{waypoints.at(0).pose.position.x += current_local_pos.pose.position.x; //set with relative position herewaypoints.at(0).pose.position.y += current_local_pos.pose.position.y;waypoints.at(0).pose.position.z += current_local_pos.pose.position.z;}pose = waypoints.at(0);
}
elsepose = waypoints.at(current_wpindex);
模式切换
本例程的最后一部分内容是处理飞车的模式切换。当飞车在陆地车模式下到达最后一个航路点时,程序将调用模式转换服务将飞车切换到多旋翼模式。一旦切换成功,航路点索引就会被清零,飞车将会起飞并沿相同的航路点飞行。
/*mode switching or disarm after last waypoint*/
if (current_wpindex == waypoints.size()-1 && _flag_last_wp_reached){if (_flyingrover_mode == FLYINGROVER_MODE::ROVER){//request to switch to multicopter modeif( current_extendedstate.flyingrover_state== mavros_msgs::ExtendedState::FLYINGROVER_STATE_ROVER &&(ros::Time::now() - last_request > ros::Duration(5.0))){if( command_long_client.call(switch_to_mc_cmd) && switch_to_mc_cmd.response.success){ROS_INFO("Flyingrover multicopter mode cmd activated");//update mode for next round_flyingrover_mode = FLYINGROVER_MODE::MULTICOPTER;current_wpindex = 0;_flag_last_wp_reached = false;}last_request = ros::Time::now();}}else if (_flyingrover_mode == FLYINGROVER_MODE::MULTICOPTER){//disarm when landed and the vehicle is heading for the last waypointif (current_extendedstate.landed_state == mavros_msgs::ExtendedState::LANDED_STATE_LANDING){if( current_state.armed &&(ros::Time::now() - last_request > ros::Duration(5.0))){if( arming_client.call(disarm_cmd) && arm_cmd.response.success){ROS_INFO("Vehicle disarmed");is_tko_inited_flag = false;is_tko_finished = false;}last_request = ros::Time::now();}}}
}
如何进行实测
现在可以将飞车拿到室外进行实测了。为避免意外,用户需严格按照如下流程操作:
将电池及线固定好,确保在飞行中不会发生脱落。
确保所有开关都处于初始位置,且油门通道已拉到最低。
电池上电。
等待GPS锁定:通常2-3分钟后我们可听到提示音,同时飞控上的LED会变为绿色。
确保飞手已就位,且飞车周围没有人。等待几分钟,机载电脑启动后可通过本地Wi-Fi网络进行远程登录,确认 /src/catkinws_offboard/src/offboard_flyingrover/launch/waypoints_xyzy.yaml目录下的航路点任务,然后通过如下指令启动offboard控制单元:
# launch a terminalcd ~/src/catkinws_offboardsource devel/setup.bashroslaunch mavros px4.launch fcu_url:="/dev/ttyPixhawk:921600"# launch a new terminalcd ~/src/catkinws_offboardsource devel/setup.bashroslaunch offboard_flyingrover off_mission.launch
拉低油门摇杆,同时右推偏航摇杆进行机器解锁,将听到一个长音提示。
使用特定的摇杆(例如通道7)切换到offboard模式,飞车将自动启动航路点任务。恭喜飞行成功!
如何购买
Kerloud无人飞车可以在云讷科技的官方淘宝店铺采购获得:
https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-23259098032.16.20804e895t5Ir2&id=654976354925
Kerloud 飞车在线控制C++教程相关推荐
- 飞车竞速商业游戏制作教程
最近刚发布了一个关于赛车竞速的视频课程,属于跑酷类型的游戏,类似天天飞车,属于一款真正的商业游戏,目前,跑酷类型的游戏在市场上的反响还是不错的,其实任何类型的游戏只要玩法新颖,用户基础都是有的. 视频 ...
- 5教程 watchout_《极品飞车10:卡本峡谷》秘籍
您可能感兴趣的话题: 极品飞车10 核心提示:极品飞车10:生死卡本谷(2006年)有25条全新赛道.增加了录像中的控制视角功能,你还可以为自己的赛车添加新图案以及改良你的赛车装备. 极品飞车10:生 ...
- 酷!GitHub开发者自研火星车,开发教程全面开源
设计: jakkra,排版整理:晓宇 微信公众号:芯片之家(ID:chiphome-dy) 火星车,听起来好遥远,但在开源社区 GitHub 中,开发者雅各布 · 克兰茨(Jakob Krantz)给 ...
- 教程┊解决使用USB键盘进行游戏后按任意键出现蓝屏的错误
教程┊解决使用USB键盘进行游戏后按任意键出现蓝屏的错误 解决方法批处理删除软件: /Files/bisonjob/qqusb.zip 近些天来,我遇到了很多次蓝屏故障,特别是在进入游戏按按键的时 ...
- 经典ps教程600例 打造ps高手
经典ps教程600例 打造ps高手 Photoshop CS魔术,制作神秘魔眼 Photoshop教程:制作熊熊的火焰在燃烧 Photoshop教程活用通道 Photoshop换头术巧妙修改闭眼照片 ...
- 详细的辅助开发教程,从入门到精通
大家玩游戏最烦的人应该是开挂的人了吧? 他们直接破坏了游戏的公平性和平衡性. 今天我们要给大家说的是辅助,不是外挂. 辅助的存在和外挂有一定的类似性,但是又是完全两样的. 比如,他们都是第三方软件/程 ...
- qq登录界面句柄_注册QQ飞车日服账号
有很多小伙伴都问过我日服的QQ飞车该如何去注册,因为日服现在开正式服不久,国服好多玩家想去里面"一展宏图",接下来就给大家出一期教程如何去注册日服飞车. 首先你必须去下载一个加速器 ...
- Away3D4.0入门教程
好吧,我知道有很多人不会有兴趣一点点把教程全看完,所以,我先在这帖子里集中发布一些基础的,但大家又非常关心的问题, 至于具体细节怎么实现,我会在以后的教程中慢慢完善,这里仅是为了提供给那些有一定动手能 ...
- 手游扫码登录神器教程
什么是"扫码登录手游"简单来说,就是不用对方的微信账号密码,直接让对方扫一扫二维码,即可使用对方的账号登录游戏或者应用程序. 你是否为了这个怎么扫码登录游戏不会而烦恼?每次朋友 ...
最新文章
- 多项目管理,研发管理,敏捷开发软件
- 「学习笔记」多项式相关
- Python | threading01 - 创建两个同时运行的子线程
- Linux CPU占用率监控工具小结
- Ubuntu下GTK的安装、编译和测试
- 浅谈语音识别技术的发展趋势与应用前景
- 《人月神话》读书笔记之第1章焦油坑
- 电气专业学校排名全国计算机专业学校排名,电气工程及其自动化专业学校排名...
- html表单代码有哪些,HTML常用代码有哪些
- android win7共享文件夹,win7系统共享文件夹如何用手机看电脑里面的电影
- JITSI开源视频直播
- HDR高动态范围图像处理算法
- 计算机网络链接密码,怎么连接局域网中计算机网络密码方法介绍
- Nginx网页优化(隐藏版本号,日志分割,更改进程数,网页压缩,防盗链详
- 千粉缔造760w播放!B站“新人”UP主在B站怎么加速上位?
- 数学词汇的英译,写文章,读文献必备
- 重装java后hadoop配置文件的修改
- c语言 数字翻译成英文,100数字翻译成英语?
- hyper graph 超图
- 从零开始5——简陋版坦克大战(2)
热门文章
- P沟道中压大电流MOS
- geth配置中,genesis.json的几个问题
- 发票专用驱动sjz_“数智企业财税云领”增值税专用发票主题交流会圆满举办| 从专票电子化开始 开启企业数智化之旅...
- 网络工程师(软考)学习笔记8--数字调制技术及脉冲编码调制
- 记一次基于强化学习的有向图搜索
- 落花虽有意,流水本无情
- python自己做个定时器_简单实现python定时器
- c语言通过结构体实现班车预约系统
- 计算机如何压缩文件?
- 中国木材3D打印机市场行业投资分析及前景趋势预测报告2022-2028年