PX4从放弃到精通(二十三):仿真
文章目录
- 前言
- 一、java仿真
- 单机仿真
- 设置仿真时间速度
- 多机仿真
- 二、硬件在环仿真
- 三、mavros offboard仿真例程
- 1.创建工作空间
- 2.创建功能包
- 四、MAVROS多机仿真
前言
Ubuntu18.04
一、java仿真
单机仿真
在源码路径下执行:
make px4_sitl_default jmavsim
设置仿真时间速度
export PX4_SIM_SPEED_FACTOR 时间倍速
例如:
export PX4_SIM_SPEED_FACTOR=2
make px4_sitl_default jmavsim
多机仿真
参考https://docs.px4.io/master/zh/simulation/multi_vehicle_simulation_gazebo.html
1.编译PX4
make px4_sitl_default
gazebo多机仿真
以五架为例,-m后面表示用哪个模型,-n后面表示多少架。这种仿真无法用nsh终端
Tools/gazebo_sitl_multiple_run.sh -m iris -n 5
jmavsim多机仿真
设置无人机架数
./Tools/sitl_multiple_run.sh 无人机架数
例如三架无人机
./Tools/sitl_multiple_run.sh 3
在该终端下启动:
./Tools/jmavsim_run.sh -l
打开新终端,依次启动每架无人机
./Tools/jmavsim_run.sh -p 4560 -l
每个终端只能启动一架无人机,每架无人机的端口要不一致,例如分别启动:
./Tools/jmavsim_run.sh -p 4560 -l
./Tools/jmavsim_run.sh -p 4561 -l
./Tools/jmavsim_run.sh -p 4562 -l
打开地面站可以看到链接了多架无人机。
二、硬件在环仿真
以四旋翼为例
参考链接
https://dev.px4.io/master/zh/simulation/hitl.html
1
将飞控连接到地面站,机架类型选择HIL Quadcopter X
2
激活 HITL 模式 安全/硬件在环仿真 选择HIL ENABLED
3
(可选) 配置操纵杆和故障保护。 Set the following parameters in order to use a joystick instead of an RC remote control transmitter:
COM_RC_IN_MODE 更改为 "Joystick/No RC Checks". 这允许操纵杆输入并禁用 RC 输入检查。NAV_RCL_ACT to "Disabled". 这可确保在没有无线遥控的情况下运行 HITL 时 RC 失控保护不会介入。
4将地面站的自动的自动连接到下列设备下面的选项只勾选UDP,否则当飞控连接到电脑后,打开地面站会自动连接到飞控,这个时候再打开仿真,会因为usb端口被占用而无法开启仿真。
只勾选UDP后,飞控不会自动连接到地面只能。仿真先通过USB连接飞控,再通过UDP连接地面站,就不会冲突。
5
先将飞控连接到电脑并等待其启动,在Firmware目录打开终端
执行
./Tools/jmavsim_run.sh -q -d /dev/ttyACM0 -b 921600 -r 250
即可仿真
通过游戏手柄可以控制无人机
注意如果在仿真时遥控器打开并连接上了无人机,则游戏手柄就无法控制无人机,只能用遥控器控制无人机
三、mavros offboard仿真例程
1.创建工作空间
mkdir -p Offboard_ws/src
cd ~/Offboard_ws/src
catkin_init_workspace
cd ~/Offboard_ws/
catkin_make
echo "source ~/Offboard_ws/devel/setup.bash">>~/.bashrc
source ~/.bashrc
echo $ROS_PACKAGE_PATH
如果上面的步骤执行正确的话,最后一步会显示工作空间路径
Offboard_ws/src:以及ROS安装路径/opt/ros/melodic/share
2.创建功能包
cd ~/Offboard_ws/src
catkin_create_pkg offboard roscpp std_msgs geometry_msgs mavros_msgs
cd offboard/src
gedit offboard_node.cpp
复制以下代码进去
#include <ros/ros.h>
#include <geometry_msgs/PoseStamped.h>
#include <mavros_msgs/CommandBool.h>
#include <mavros_msgs/SetMode.h>
#include <mavros_msgs/State.h>mavros_msgs::State current_state;
void state_cb(const mavros_msgs::State::ConstPtr& msg){current_state = *msg;
}int main(int argc, char **argv)
{ros::init(argc, argv, "offb_node");ros::NodeHandle nh;ros::Subscriber state_sub = nh.subscribe<mavros_msgs::State>("mavros/state", 10, state_cb);ros::Publisher local_pos_pub = nh.advertise<geometry_msgs::PoseStamped>("mavros/setpoint_position/local", 10);ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>("mavros/cmd/arming");ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>("mavros/set_mode");//the setpoint publishing rate MUST be faster than 2Hzros::Rate rate(20.0);// wait for FCU connectionwhile(ros::ok() && !current_state.connected){ros::spinOnce();rate.sleep();}geometry_msgs::PoseStamped pose;pose.pose.position.x = 0;pose.pose.position.y = 0;pose.pose.position.z = 2;//send a few setpoints before startingfor(int i = 100; ros::ok() && i > 0; --i){local_pos_pub.publish(pose);ros::spinOnce();rate.sleep();}mavros_msgs::SetMode offb_set_mode;offb_set_mode.request.custom_mode = "OFFBOARD";mavros_msgs::CommandBool arm_cmd;arm_cmd.request.value = true;ros::Time last_request = ros::Time::now();while(ros::ok()){if( current_state.mode != "OFFBOARD" &&(ros::Time::now() - last_request > ros::Duration(5.0))){if( set_mode_client.call(offb_set_mode) &&offb_set_mode.response.mode_sent){ROS_INFO("Offboard enabled");}last_request = ros::Time::now();} else {if( !current_state.armed &&(ros::Time::now() - last_request > ros::Duration(5.0))){if( arming_client.call(arm_cmd) &&arm_cmd.response.success){ROS_INFO("Vehicle armed");}last_request = ros::Time::now();}}local_pos_pub.publish(pose);ros::spinOnce();rate.sleep();}return 0;
}
cd ..
gedit CMakeLists.txt
在最末尾添加如下内容后保存退出
add_executable(${PROJECT_NAME}_node src/offboard_node.cpp)
target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES})
然后编译
cd ~/Offboard_ws
catkin_make
然后先
roslaunch px4 mavros_posix_sitl.launch
再启动offboard节点
rosrun offboard offboard_node
正常的话无人机会起飞至2米
注意export 开头的环境变量必须放在最下面,source开头的如果放在最下的话,会导致无法使用roslaunch px4 mavros_posix_sitl.launch,以及直接启动launch文件是提示找不到路径
四、MAVROS多机仿真
添加多机仿真的脚本的环境变量
我这里的Firmware在home目录下,添加如下到.bashrc
source ~/Firmware/Tools/setup_gazebo.bash ~/Firmware/ ~/Firmware/build/px4_sitl_default
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/Firmware
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/Firmware/Tools/sitl_gazebo
修改launch文件multi_uav_mavros_sitl.launch
格式如下
<?xml version="1.0"?>
<launch><!-- MAVROS posix SITL environment launch script --><!-- launches Gazebo environment and 2x: MAVROS, PX4 SITL, and spawns vehicle --><!-- vehicle model and world --><arg name="est" default="ekf2"/><arg name="vehicle" default="iris"/><arg name="world" default="$(find mavlink_sitl_gazebo)/worlds/empty.world"/><!-- gazebo configs --><arg name="gui" default="true"/><arg name="debug" default="false"/><arg name="verbose" default="false"/><arg name="paused" default="false"/><!-- Gazebo sim --><include file="$(find gazebo_ros)/launch/empty_world.launch"><arg name="gui" value="$(arg gui)"/><arg name="world_name" value="$(arg world)"/><arg name="debug" value="$(arg debug)"/><arg name="verbose" value="$(arg verbose)"/><arg name="paused" value="$(arg paused)"/></include><!-- UAV0 --><group ns="uav0"><!-- MAVROS and vehicle configs --><arg name="ID" value="0"/><arg name="fcu_url" default="udp://:14540@localhost:14580"/><!-- PX4 SITL and vehicle spawn --><include file="$(find px4)/launch/single_vehicle_spawn.launch"><arg name="x" value="0"/><arg name="y" value="0"/><arg name="z" value="0"/><arg name="R" value="0"/><arg name="P" value="0"/><arg name="Y" value="0"/><arg name="vehicle" value="$(arg vehicle)"/><arg name="mavlink_udp_port" value="14560"/><arg name="mavlink_tcp_port" value="4560"/><arg name="ID" value="$(arg ID)"/></include><!-- MAVROS --><include file="$(find mavros)/launch/px4.launch"><arg name="fcu_url" value="$(arg fcu_url)"/><arg name="gcs_url" value=""/><arg name="tgt_system" value="$(eval 1 + arg('ID'))"/><arg name="tgt_component" value="1"/></include></group><!-- UAV1 --><group ns="uav1"><!-- MAVROS and vehicle configs --><arg name="ID" value="1"/><arg name="fcu_url" default="udp://:14541@localhost:14581"/><!-- PX4 SITL and vehicle spawn --><include file="$(find px4)/launch/single_vehicle_spawn.launch"><arg name="x" value="1"/><arg name="y" value="0"/><arg name="z" value="0"/><arg name="R" value="0"/><arg name="P" value="0"/><arg name="Y" value="0"/><arg name="vehicle" value="$(arg vehicle)"/><arg name="mavlink_udp_port" value="14561"/><arg name="mavlink_tcp_port" value="4561"/><arg name="ID" value="$(arg ID)"/></include><!-- MAVROS --><include file="$(find mavros)/launch/px4.launch"><arg name="fcu_url" value="$(arg fcu_url)"/><arg name="gcs_url" value=""/><arg name="tgt_system" value="$(eval 1 + arg('ID'))"/><arg name="tgt_component" value="1"/></include></group><!-- UAV2 --><group ns="uav2"><!-- MAVROS and vehicle configs --><arg name="ID" value="2"/><arg name="fcu_url" default="udp://:14542@localhost:14582"/><!-- PX4 SITL and vehicle spawn --><include file="$(find px4)/launch/single_vehicle_spawn.launch"><arg name="x" value="0"/><arg name="y" value="1"/><arg name="z" value="0"/><arg name="R" value="0"/><arg name="P" value="0"/><arg name="Y" value="0"/><arg name="vehicle" value="$(arg vehicle)"/><arg name="mavlink_udp_port" value="14562"/><arg name="mavlink_tcp_port" value="4562"/><arg name="ID" value="$(arg ID)"/></include><!-- MAVROS --><include file="$(find mavros)/launch/px4.launch"><arg name="fcu_url" value="$(arg fcu_url)"/><arg name="gcs_url" value=""/><arg name="tgt_system" value="$(eval 1 + arg('ID'))"/><arg name="tgt_component" value="1"/></include></group>
编写多机控制节点,控制不同的无人机发布不同的话题就行了
/*** @file offb_node.cpp* @brief Offboard control example node, written with MAVROS version 0.19.x, PX4 Pro Flight* Stack and tested in Gazebo SITL*/#include <ros/ros.h>
#include <geometry_msgs/PoseStamped.h>
#include <mavros_msgs/CommandBool.h>
#include <mavros_msgs/SetMode.h>
#include <mavros_msgs/State.h>mavros_msgs::State current_state;
void state_cb(const mavros_msgs::State::ConstPtr& msg){current_state = *msg;
}int main(int argc, char **argv)
{ros::init(argc, argv, "offb_node");ros::NodeHandle nh;ros::Subscriber state_sub = nh.subscribe<mavros_msgs::State>("mavros/state", 10, state_cb);ros::Publisher local_pos_pub = nh.advertise<geometry_msgs::PoseStamped>("mavros/setpoint_position/local", 10);ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>("mavros/cmd/arming");ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>("mavros/set_mode");ros::Publisher local_pos_pub1 = nh.advertise<geometry_msgs::PoseStamped>("uav1/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client1 = nh.serviceClient<mavros_msgs::CommandBool>("uav1/mavros/cmd/arming");ros::ServiceClient set_mode_client1 = nh.serviceClient<mavros_msgs::SetMode>("uav1/mavros/set_mode");ros::Publisher local_pos_pub2 = nh.advertise<geometry_msgs::PoseStamped>("uav2/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client2 = nh.serviceClient<mavros_msgs::CommandBool>("uav2/mavros/cmd/arming");ros::ServiceClient set_mode_client2 = nh.serviceClient<mavros_msgs::SetMode>("uav2/mavros/set_mode");ros::Publisher local_pos_pub3 = nh.advertise<geometry_msgs::PoseStamped>("uav3/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client3 = nh.serviceClient<mavros_msgs::CommandBool>("uav3/mavros/cmd/arming");ros::ServiceClient set_mode_client3 = nh.serviceClient<mavros_msgs::SetMode>("uav3/mavros/set_mode");ros::Publisher local_pos_pub4 = nh.advertise<geometry_msgs::PoseStamped>("uav4/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client4 = nh.serviceClient<mavros_msgs::CommandBool>("uav4/mavros/cmd/arming");ros::ServiceClient set_mode_client4= nh.serviceClient<mavros_msgs::SetMode>("uav4/mavros/set_mode");ros::Publisher local_pos_pub5 = nh.advertise<geometry_msgs::PoseStamped>("uav5/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client5 = nh.serviceClient<mavros_msgs::CommandBool>("uav5/mavros/cmd/arming");ros::ServiceClient set_mode_client5= nh.serviceClient<mavros_msgs::SetMode>("uav5/mavros/set_mode");ros::Publisher local_pos_pub6 = nh.advertise<geometry_msgs::PoseStamped>("uav6/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client6 = nh.serviceClient<mavros_msgs::CommandBool>("uav6/mavros/cmd/arming");ros::ServiceClient set_mode_client6= nh.serviceClient<mavros_msgs::SetMode>("uav6/mavros/set_mode");ros::Publisher local_pos_pub7 = nh.advertise<geometry_msgs::PoseStamped>("uav7/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client7 = nh.serviceClient<mavros_msgs::CommandBool>("uav7/mavros/cmd/arming");ros::ServiceClient set_mode_client7= nh.serviceClient<mavros_msgs::SetMode>("uav7/mavros/set_mode");ros::Publisher local_pos_pub8 = nh.advertise<geometry_msgs::PoseStamped>("uav8/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client8 = nh.serviceClient<mavros_msgs::CommandBool>("uav8/mavros/cmd/arming");ros::ServiceClient set_mode_client8= nh.serviceClient<mavros_msgs::SetMode>("uav8/mavros/set_mode");ros::Publisher local_pos_pub9 = nh.advertise<geometry_msgs::PoseStamped>("uav9/mavros/setpoint_position/local", 10);ros::ServiceClient arming_client9 = nh.serviceClient<mavros_msgs::CommandBool>("uav9/mavros/cmd/arming");ros::ServiceClient set_mode_client9= nh.serviceClient<mavros_msgs::SetMode>("uav9/mavros/set_mode");//the setpoint publishing rate MUST be faster than 2Hzros::Rate rate(20.0);geometry_msgs::PoseStamped pose,pose1,pose2,pose3,pose4,pose5,pose6,pose7,pose8,pose9;pose.pose.position.x = 0;pose.pose.position.y = 0;pose.pose.position.z = 6;pose1.pose.position.x = 0;pose1.pose.position.y = 0;pose1.pose.position.z = 6;pose2.pose.position.x = 0;pose2.pose.position.y = 0;pose2.pose.position.z = 6;pose3.pose.position.x = 0;pose3.pose.position.y = 0;pose3.pose.position.z = 6;pose4.pose.position.x =0;pose4.pose.position.y =0;pose4.pose.position.z =6;pose5.pose.position.x =0;pose5.pose.position.y =0;pose5.pose.position.z =6;pose6.pose.position.x =0;pose6.pose.position.y =0;pose6.pose.position.z =6;pose7.pose.position.x =0;pose7.pose.position.y =0;pose7.pose.position.z =6;pose8.pose.position.x =0;pose8.pose.position.y =0;pose8.pose.position.z =6;pose9.pose.position.x =0;pose9.pose.position.y =0;pose9.pose.position.z =6;mavros_msgs::SetMode offb_set_mode;offb_set_mode.request.custom_mode = "TAKEOFF";mavros_msgs::CommandBool arm_cmd;arm_cmd.request.value = true;ros::Time last_request = ros::Time::now();
int flag=0;while(ros::ok()){if(flag>30)
{pose.pose.position.x = 0;pose.pose.position.y = 10;pose.pose.position.z = 6;pose1.pose.position.x = 0;pose1.pose.position.y = 10;pose1.pose.position.z = 6;pose2.pose.position.x = 0;pose2.pose.position.y = 10;pose2.pose.position.z = 6;pose3.pose.position.x = 0;pose3.pose.position.y = 10;pose3.pose.position.z = 6;pose4.pose.position.x =0;pose4.pose.position.y =10;pose4.pose.position.z =6;pose5.pose.position.x =0;pose5.pose.position.y =10;pose5.pose.position.z =6;pose6.pose.position.x =0;pose6.pose.position.y =10;pose6.pose.position.z =6;pose7.pose.position.x =0;pose7.pose.position.y =10;pose7.pose.position.z =6;pose8.pose.position.x =0;pose8.pose.position.y =10;pose8.pose.position.z =6;pose9.pose.position.x =0;pose9.pose.position.y =10;pose9.pose.position.z =6;}
set_mode_client.call(offb_set_mode);
arming_client.call(arm_cmd);
local_pos_pub.publish(pose);set_mode_client1.call(offb_set_mode);
arming_client1.call(arm_cmd);
local_pos_pub1.publish(pose1);set_mode_client2.call(offb_set_mode);
arming_client2.call(arm_cmd);
local_pos_pub2.publish(pose2);set_mode_client3.call(offb_set_mode);
arming_client3.call(arm_cmd);
local_pos_pub3.publish(pose3);set_mode_client4.call(offb_set_mode);
arming_client4.call(arm_cmd);
local_pos_pub4.publish(pose4);set_mode_client5.call(offb_set_mode);
arming_client5.call(arm_cmd);
local_pos_pub5.publish(pose5);set_mode_client6.call(offb_set_mode);
arming_client6.call(arm_cmd);
local_pos_pub6.publish(pose6);set_mode_client7.call(offb_set_mode);
arming_client7.call(arm_cmd);
local_pos_pub7.publish(pose7);set_mode_client8.call(offb_set_mode);
arming_client8.call(arm_cmd);
local_pos_pub8.publish(pose8);set_mode_client9.call(offb_set_mode);
arming_client9.call(arm_cmd);
local_pos_pub9.publish(pose9);flag++;ros::spinOnce();rate.sleep();}return 0;
}
然后先执行launch文件。再执行控制节点,就可以实现多机控制
PX4从放弃到精通(二十三):仿真相关推荐
- java从入门到精通二十三(Servlet)
java从入门到精通二十三(Servlet) Servlet 说明 Servlet初步入门尝试 Servlet生命周期 Servlet方法说明和体系结构 方法说明 体系结构说明 一些优化封装 urlP ...
- PX4从放弃到精通(二十四):自定义机型
文章目录 前言 一.定义机型文件 二.修改srcparser.py 三.编译并下载固件 四.修改QGC 前言 本教程用PX4实现自定义一些新构型的载具 PX4固件版本:1.12.3 QGC版本:4.0 ...
- PX4从放弃到精通(二十五):EKF2
文章目录 前言 一.主程序 二.update() 二.predictState() 三.controlFusionModes() 四.controlGpsFusion 五.fuseGpsVelPos( ...
- PX4从放弃到精通(二十七):固定翼姿态控制
- PX4从放弃到精通(二十六):GPS驱动
- PX4从放弃到精通(二):ubuntu18.04配置px4编译环境及mavros环境
- PX4从放弃到精通(三):使用qt编译PX4
目录 前言 一.安装QT 二.生成bulid文件夹 三.配置QTCreater 四.QTCreater无法输入中文解决办法 前言 交流学习加qq:2096723956 更多保姆级PX4+ROS学习视频 ...
- SIKI学院:MySQL数据库从零到精通:二十三:课时 27 : 26-数据库的备份和恢复+课时 28 : 27-结语
目录 一.目的 1.想:提高学习效率,所以将老师的内容记录下来 二.参考 1.SIKI学院 三.注意 1.课程资源下载 1.MySQL下载地址 四.操作:成功 1.备份 1.数据库内容 1.删除数据库 ...
- PX4从放弃到精通(五):PX4中的姿态表示方法及转换关系
文章目录 前言 坐标系 无人机的姿态描述 转换关系 总结 前言 一个人可以走的更快,一群人才能走的更远,交流学习加qq:2096723956 更多保姆级PX4+ROS学习视频:https://b23. ...
最新文章
- spell_picture3.1版本windows上手动拼图的软件的升级
- 移动端app设计指南
- beta book读书俱乐部的构思
- Ubuntu安装源安装nodejs
- mongodb导出导入实例记录
- 2016 排行前20 的编程语言
- 哪款浏览器好用_超级实用!让你效率倍增的6款浏览器插件
- [No000045]最好的休息,不是睡觉!
- C语言基础编程练习(精选例题+题解)
- IBM DB2各版本下载地址
- python找电影资源_python一键电影搜索与下载
- linux 拒绝访问文件夹,文件夹拒绝访问的原因与解决办法
- 手机显示一帧的流程是如何实现?
- 云原生GIS技术全解读
- 如何配置java环境_vscode配置java环境
- minisys-单周期cpu(一) 数据通路设计
- 求超大文件上传方案( Web )
- pandas内置数据集_Pandas数据分析实战01——Abalone Data Set(鲍鱼数据集)
- 彻底解决 webpack 打包文件体积过大
- jquery上传图片本地预览插件V1.2