pixhawk的仿真SITL
仿真分为软件在环仿真(SITL)和硬件在环仿真(HITL)
软件在环仿真一共是有jMAVSim、Gazebo、AirSim这三种。jMAVSim是一个轻量级的仿真器,目前只支持四旋翼仿真。AirSim我不太清楚,没有使用过,这里就不评价了。Gazebo是我们今天的主角,支持旋翼、固定翼、倾转、小车等,是所有仿真器里支持平台最多的,也能支持多个无人机的仿真.
-
SITL(循环软件)模拟器允许您在没有任何硬件的情况下运行飞机、直升机或漫游者。
-
它是使用普通 C++ 编译器构建的自动驾驶仪代码,为您提供本机可执行文件,允许您在没有硬件的情况下测试代码的行为。
-
SITL 允许您直接在 PC 上运行 ArduPilot,无需任何特殊硬件。
-
它利用了 ArduPilot 是一种便携式自动驾驶仪,可以在各种平台上运行的事实。
-
您的 PC 只是 ArduPilot 可以构建和运行的另一个平台。
-
在 SITL 中运行时,传感器数据来自飞行模拟器中的飞行动力学模型。
-
ArduPilot 内置了广泛的车辆模拟器,并且可以连接到多个外部模拟器。
-
这使得 ArduPilot 可以在非常广泛的车辆类型上进行测试。
参考:https://www.ncnynl.com/archives/202106/4289.html
Gazebo仿真
src文件夹。这里是核心代码,即plugin(插件)代码。比如gps、imu、电机的插件,简单说如何模拟产生gps信号,就是这里的代码负责的。Gazebo自身也会提供一些默认插件,或者第三方也会提供插件,比如你要新增一个传感器,就可以找到相应的插件。
models文件夹。存放各种Gazebo模型文件。
worlds文件夹。存放Gazebo的世界环境文件。
涉及到Gazebo仿真二次开发就是如上三个文件夹,分别对应修改模型、修改模型参数、修改世界。
参考链接:https://zhuanlan.zhihu.com/p/337919677
编译:make px4_sitl_default gazebo
运行Gazebo仿真: roslaunch px4 posix_sitl.launch
运行Mavros
运行px4_command
<launch>
<!-- Gazebo configs -->
<arg name="gazebo_enable" default="true"/>
<arg name="world" default="$(find prometheus_gazebo)/gazebo_worlds/prometheus_empty.world"/>
world描述文件prometheus_empty.world包含所有在仿真过程的元素模块。包括机器人(robot)、光照、传感器和静态的物体。这个文件的格式是使用SDF格式和以.world为后缀名。
gzserver的作用是更新物理环境和产生传感器的数据。所以gzserver会读取world文件去生成和填充一个世界环境。gazebo本身就有很多world的例子。
<!-- 启动Gazebo -->
<group if="$(arg gazebo_enable)">
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(arg world)"/>
</include>
</group>
<!--无人机编号-->
<arg name="uav1_id" default="1"/>
<!-- 无人机初始位置 -->
<arg name="uav1_init_x" default="0.0"/>
<arg name="uav1_init_y" default="0.0"/>
<arg name="uav1_init_yaw" default="0.0"/>
<arg name="sdf" default="$(find prometheus_gazebo)/gazebo_models/uav_models/multi_p450/p450_uav$(arg uav1_id)/p450_uav$(arg uav1_id).sdf"/>
<!-- 1号无人机 -->
<include file="$(find prometheus_gazebo)/launch_basic/sitl_px4_outdoor.launch">
<arg name="uav_id" value="$(arg uav1_id)"/>
<arg name="sdf" value="$(arg sdf)"/>
<arg name="model" value="p450_uav$(arg uav1_id)"/>
<arg name="uav_init_x" value="$(arg uav1_init_x)"/>
<arg name="uav_init_y" value="$(arg uav1_init_y)"/>
<arg name="uav_init_z" value="0.15"/>
<arg name="uav_init_yaw" value="$(arg uav1_init_yaw)"/>
</include>
</launch>
<!-- Offboard端口号(用于飞控与Mavros进行通讯) udp_offboard_port_local = 14580 + ID -->
<!-- Offboard端口号(用于飞控与Mavros进行通讯) udp_offboard_port_remote = 14540 + ID -->
<!-- 启动MAVROS -->
<arg name="udp_offboard_port_remote" value="$(eval 14540 + arg('ID'))"/>
<arg name="udp_offboard_port_local" value="$(eval 14580 + arg('ID'))"/>
<node pkg="mavros" type="mavros_node" name="mavros" output="screen">
<param name="fcu_url" value="udp://:$(arg udp_offboard_port_remote)@localhost:$(arg udp_offboard_port_local)"/>
<param name="gcs_url" value="" />
<param name="target_system_id" value="$(eval 1 + arg('ID'))"/>
<param name="target_component_id" value="1" />
<rosparam command="load" file="$(find prometheus_gazebo)/config/mavros_config/px4_config_outdoor.yaml" />
<rosparam command="load" file="$(find prometheus_gazebo)/config/mavros_config/px4_pluginlists_outdoor.yaml" />
</node>
无人机控制节点
<launch>
<arg name="uav_id" default="1"/>
<arg name="sim_mode" default="true"/>
<arg name="flag_printf" default="true"/>
<!-- 如果是matlab配置为ATT_CTRL_MODE,则此处要设置为True-->
<arg name="control/enable_external_control" default="false"/>
<arg name="launch_prefix" default="" />
<!-- 启动uav_control_main -->
<node pkg="prometheus_uav_control" type="uav_control_main" name="uav_control_main_$(arg uav_id)" output="screen" launch-prefix="$(arg launch_prefix)">
<param name="uav_id" value="$(arg uav_id)" />
<param name="sim_mode" value="$(arg sim_mode)" />
<param name="flag_printf" value="$(arg flag_printf)" />
<param name="control/enable_external_control" value="$(arg control/enable_external_control)" />
通过加载yaml文件来设置param:
下面这句指令也就是执行了 load 命令来实现装载文件的命令。
<rosparam command="load" file="$(find prometheus_uav_control)/launch/uav_control_outdoor.yaml" />
</node>
<!-- 启动虚拟摇杆驱动 -->
<arg name="joy_enable" default="true"/>
<group if="$(arg joy_enable)">
<node pkg="prometheus_uav_control" type="joy_node" name="joy_node" output="screen">
</node>
</group>
</launch>
<launch>
<node pkg="prometheus_demo" type="circular_trajectory_control" name="circular_trajectory_control" output="screen">
<param name="uav_id" value="1"/>
</node>
</launch>
pub_fake_rc_in[i] = nh_.advertise<mavros_msgs::RCIn>(agent_name + "/prometheus/fake_rc_in", 1);
rostopic echo /uav1/prometheus/fake_rc_in
发布的是通道的数值
nh.advertise<prometheus_msgs::UAVControlState>("/uav" + std::to_string(uav_id) + "/prometheus/control_state", 1);