ROS1(20.04 noetic) + PX4 + AirSim
博主使用的版本配置如下:
- ROS: 20.04 noetic 【echo $ROS_DISTRO】
- PX4: v1.13.2 【找到 PX4 安裝目錄,git describe --tags】
- AirSim: 1.7.0 【找到\Unreal\Plugins\AirSim這個目錄,進入后,打開AirSim.uplugin文件查看版本】

最終效果

安裝 ROS
- 20.04 noetic
參考鏈接: 小魚的一鍵安裝系列
wget http://fishros.com/install -O fishros && . fishros
PX4 開發環境搭建
- MAVROS + QGC + PX4
參考鏈接: PX4 仿真環境開發整理
遇到報錯參考鏈接: make px4_sitl_default gazebo出錯
遇到報錯參考鏈接: Gazebo終端顯示[Err] [InsertModelWidget.cc:403] Missing model.config for model
遇到報錯參考鏈接: px4 運行mavros仿真
AirSim 仿真平臺搭建
- UE4 + AirSim
使用Airsim的ros包
遇到報錯參考鏈接: 解決Ubuntu系統下ROS包找不到問題:環境配置與路徑檢查詳解
AirSim 配置文件修改
settings.json
{
"SettingsVersion": 1.2,
"SimMode": "Multirotor",
"ClockType": "SteppableClock",
"Vehicles": {
"PX4": {
"VehicleType": "PX4Multirotor",
"UseSerial": false,
"LockStep": true,
"UseTcp": true,
"TcpPort": 4560,
"ControlPortLocal": 14030,
"ControlPortRemote": 14280,
"ControlIp": "remote",
"LocalHostIp": "192.168.1.5",
"Cameras": {
"CameraDepth": {
"CaptureSettings": [
{
"ImageType": 2,
"Width": 800,
"Height": 600,
"FOV_Degrees": 120,
"AutoExposureSpeed": 100,
"AutoExposureBias": 0,
"AutoExposureMaxBrightness": 0.64,
"AutoExposureMinBrightness": 0.03,
"MotionBlurAmount": 0,
"TargetGamma": 1.0,
"ProjectionMode": "",
"OrthoWidth": 5.12
}
],
"NoiseSettings": [
{
"Enabled": false,
"ImageType": 0,
"RandContrib": 0.2,
"RandSpeed": 100000.0,
"RandSize": 500.0,
"RandDensity": 2,
"HorzWaveContrib":0.03,
"HorzWaveStrength": 0.08,
"HorzWaveVertSize": 1.0,
"HorzWaveScreenSize": 1.0,
"HorzNoiseLinesContrib": 1.0,
"HorzNoiseLinesDensityY": 0.01,
"HorzNoiseLinesDensityXY": 0.5,
"HorzDistortionContrib": 1.0,
"HorzDistortionStrength": 0.002
}
],
"Gimbal": {
"Stabilization": 0,
"Pitch": 0, "Roll": 0, "Yaw": 0
},
"X": 0, "Y": 0, "Z": -1,
"Pitch": 0, "Roll": 0, "Yaw": 0,
"UnrealEngine": {
"PixelFormatOverride": [
{
"ImageType": 0,
"PixelFormat": 0
}
]
}
},
"CameraImage": {
"CaptureSettings": [
{
"ImageType": 0,
"Width": 800,
"Height": 600,
"FOV_Degrees": 120,
"AutoExposureSpeed": 100,
"AutoExposureBias": 0,
"AutoExposureMaxBrightness": 0.64,
"AutoExposureMinBrightness": 0.03,
"MotionBlurAmount": 0,
"TargetGamma": 1.0,
"ProjectionMode": "",
"OrthoWidth": 5.12
}
],
"X": 0, "Y": 0, "Z": -1,
"Pitch": 0, "Roll": 0, "Yaw": 0
}
},
"Sensors":{
"Magnetometer": {
"SensorType": 4,
"Enabled": true
},
"Barometer":{
"SensorType": 1,
"Enabled": true,
"PressureFactorSigma": 0.0001825
},
"Imu": {
"SensorType": 2,
"Enabled" : true,
"AngularRandomWalk": 0.3,
"GyroBiasStabilityTau": 500,
"GyroBiasStability": 4.6,
"VelocityRandomWalk": 0.24,
"AccelBiasStabilityTau": 800,
"AccelBiasStability": 36
},
"Gps": {
"SensorType": 3,
"Enabled" : true,
"EphTimeConstant": 0.9,
"EpvTimeConstant": 0.9,
"EphInitial": 25,
"EpvInitial": 25,
"EphFinal": 0.1,
"EpvFinal": 0.1,
"EphMin3d": 3,
"EphMin2d": 4,
"UpdateLatency": 0.2,
"UpdateFrequency": 50,
"StartupDelay": 1
},
"Lidar": {
"SensorType": 6,
"Enabled": true,
"NumberOfChannels": 16,
"RotationsPerSecond": 10,
"PointsPerSecond": 100000,
"X": 0, "Y": 0, "Z": -1,
"Roll": 0, "Pitch": 0, "Yaw": 0,
"VerticalFOVUpper": 10,
"VerticalFOVLower": -10,
"HorizontalFOVStart": -20,
"HorizontalFOVEnd": 20,
"DrawDebugPoints": true,
"DataFrame": "SensorLocalFrame"
},
"DistanceDown": {
"SensorType": 5,
"Enabled" : true,
"MinDistance": 0.1,
"MaxDistance": 40,
"X": 0, "Y": 0, "Z": -0.5,
"Yaw": 0, "Pitch": -90, "Roll": 0,
"DrawDebugPoints": true,
"ExternalController": true
}
},
"Parameters": {
"NAV_RCL_ACT": 0,
"NAV_DLL_ACT": 0,
"COM_OBS_AVOID": 0
}
}
}
}
安裝 Micro-XRCE-DDS-Agent
- 安裝指令
$ git clone https://github.com/eProsima/Micro-XRCE-DDS-Client.git
$ cd Micro-XRCE-DDS-Client
$ mkdir build && cd build
$ cmake ..
$ make -j8
$ sudo make install
$ sudo ldconfig /usr/local/lib/
$ MicroXRCEAgent --help
開發流程
yehuo@zyl:~$ mkdir px4_airsim_ros1_ws
yehuo@zyl:~$ cd px4_airsim_ros1_ws
yehuo@zyl:~/px4_airsim_ros1_ws$ mkdir src
yehuo@zyl:~/px4_airsim_ros1_ws$ cd src
yehuo@zyl:~/px4_airsim_ros1_ws/src$ catkin_create_pkg offboard_py rospy
yehuo@zyl:~/px4_airsim_ros1_ws/src$ cd ..
yehuo@zyl:~/px4_airsim_ros1_ws$ catkin build
yehuo@zyl:~/px4_airsim_ros1_ws$ source devel/setup.bash
yehuo@zyl:~/px4_airsim_ros1_ws$ roscd offboard_py
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py$ mkdir scripts
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py$ cd scripts
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py/scripts$ touch offb_node.py
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py/scripts$ chmod +x offb_node.py
offb_node.py
"""
* File: offb_node.py
* Stack and tested in Gazebo 9 SITL
"""
#! /usr/bin/env python
import rospy
from geometry_msgs.msg import PoseStamped
from mavros_msgs.msg import State
from mavros_msgs.srv import CommandBool, CommandBoolRequest, SetMode, SetModeRequest
current_state = State()
def state_cb(msg):
global current_state
current_state = msg
if __name__ == "__main__":
rospy.init_node("offb_node_py")
state_sub = rospy.Subscriber("mavros/state", State, callback = state_cb)
local_pos_pub = rospy.Publisher("mavros/setpoint_position/local", PoseStamped, queue_size=10)
rospy.wait_for_service("/mavros/cmd/arming")
arming_client = rospy.ServiceProxy("mavros/cmd/arming", CommandBool)
rospy.wait_for_service("/mavros/set_mode")
set_mode_client = rospy.ServiceProxy("mavros/set_mode", SetMode)
# Setpoint publishing MUST be faster than 2Hz
rate = rospy.Rate(20)
# Wait for Flight Controller connection
while(not rospy.is_shutdown() and not current_state.connected):
rate.sleep()
pose = PoseStamped()
pose.pose.position.x = 0
pose.pose.position.y = 0
pose.pose.position.z = 2
# Send a few setpoints before starting
for i in range(100):
if(rospy.is_shutdown()):
break
local_pos_pub.publish(pose)
rate.sleep()
offb_set_mode = SetModeRequest()
offb_set_mode.custom_mode = 'OFFBOARD'
arm_cmd = CommandBoolRequest()
arm_cmd.value = True
last_req = rospy.Time.now()
while(not rospy.is_shutdown()):
if(current_state.mode != "OFFBOARD" and (rospy.Time.now() - last_req) > rospy.Duration(5.0)):
if(set_mode_client.call(offb_set_mode).mode_sent == True):
rospy.loginfo("OFFBOARD enabled")
last_req = rospy.Time.now()
else:
if(not current_state.armed and (rospy.Time.now() - last_req) > rospy.Duration(5.0)):
if(arming_client.call(arm_cmd).success == True):
rospy.loginfo("Vehicle armed")
last_req = rospy.Time.now()
local_pos_pub.publish(pose)
rate.sleep()
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py/scripts$ roscd offboard_py
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py$ mkdir launch
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py$ cd launch
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py/launch$ touch start_offb.launch
start_offb.launch
<?xml version="1.0"?>
<launch>
<!-- Include the MAVROS node with SITL and Gazebo -->
<!-- <include file="$(find px4)/launch/mavros_posix_sitl.launch"></include> -->
<!-- MAVROS 僅連接 AirSim 中的 PX4 SITL -->
<arg name="fcu_url" default="udp://:14540@192.168.1.5:14557"/>
<arg name="gcs_url" default=""/>
<arg name="respawn_mavros" default="false"/>
<include file="$(find mavros)/launch/px4.launch">
<arg name="fcu_url" value="$(arg fcu_url)"/>
<arg name="gcs_url" value="$(arg gcs_url)"/>
<arg name="respawn_mavros" value="$(arg respawn_mavros)"/>
</include>
<!-- Offboard 控制節點 -->
<node pkg="offboard_py" type="offb_node.py" name="offb_node_py" required="true" output="screen"/>
</launch>
yehuo@zyl:~/px4_airsim_ros1_ws/src/offboard_py/launch$ roslaunch offboard_py start_offb.launch


流程框架整理
- step1: 啟動 AirSim
- step2: 啟動 PX4
yehuo@zyl:~/下載/PX4_Firmware$ make px4_sitl_default none_iris
- step3: 啟動 DDS
yehuo@zyl:~$ MicroXRCEAgent udp4 -p 8888
- step4: 啟動 MAVROS (Python版本)
yehuo@zyl:~$ roscore
yehuo@zyl:~$ roslaunch offboard_py start_offb.launch
- step5: 查看話題是否成功獲取
yehuo@zyl:~$ rostopic list

浙公網安備 33010602011771號