无人机指南
无人机指南
首先安装一个双系统,详细安装请看,这里面自动配好了ros2和ubuntu
无人机的环境配置
一:在 Gazebo 搭建 PX4 无人机仿真环境 需要经过以下步骤:
模块 | 作用 |
---|---|
PX4(SITL) | 飞控程序运行环境(源码编译后作为核心控制器) |
Gazebo | 仿真平台(提供世界、物理模拟、传感器模拟) |
QGroundControl | 图形界面管理飞控(切模式、监控飞行状态) |
ROS2 | 运行你的算法(导航/目标检测/规划等) |
MAVLink | PX4 与 ROS/QGC 等通信协议 |
MAVROS | ROS <-> MAVLink 的桥梁,提供话题与服务 |
RViz2 | 可视化 ROS 信息(轨迹、传感器数据、地图等) |
px4联动总览图
[ QGroundControl ]↑│ MAVLink over UDP↓[ ROS2 / MAVROS ] ←→ PX4 (SITL) ←→ Gazebo11 (世界 + 传感器 + 动力学)↑│ MAVLink↓控制命令源(Python/Cpp/ROS2节点写控制逻辑)
eg:
你写了一个 ROS 2 节点控制无人机飞一个正方形轨迹:
- 你发布位置目标 → ROS 2 topic(比如
/mavros/setpoint_position/local
); - DDS 把消息传给 MAVROS;
- MAVROS 转为 MAVLink 消息发给 PX4;
- PX4 的 MAVLink 接口接收指令,发布到 uORB;
- 控制器读取目标 → 计算姿态输出 → 通过 mixer → PWM 输出;
- 电调控制电机旋转;
- 飞机移动,同时 IMU/GPS 回传状态 → PX4 → MAVLink → MAVROS → ROS 2。
安装px4:
mkdir -p ~/px4_ws/src && cd ~/px4_ws #创建工作空间
cd ~/px4_ws/src
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
cd PX4-Autopilot
bash ./Tools/setup/ubuntu.sh #这个脚本会自动帮你下载好ROS 2(可选),Gazebo仿真环境,MAVLink,FastRTPS,PX4依赖的Python模块
检查是否安装完成:
make px4_sitl_default
如果能出现一个gazebo页面就说明安装成功。
建模部分:
用solidworks构建stl文件,打造物体,等建模好了之后,如果是用本机的solidworks生成的stl文件,如果要导入到虚拟机,要提前在设置中开启共享文件夹.要在gazebo.models下创建一个存放仿真环境的文件,比如fly_environment,然后创建meshes,模型文件(SDF) 和 配置文件(Config) 来定义和加载模型
meshes/ 目录主要用于存放 模型的 3D 网格文件(如 .STL、.DAE、.OBJ 等),这些网格文件用于定义模型的 视觉外观(Visual) 和 碰撞检测(Collision)。
model.config 作用
- 作用:定义 模型的基本信息,让 Gazebo 识别该模型。
- 主要包含:
- 模型名称
- SDF 版本
- 作者信息
- 描述
- 模型资源
model.config
示例
文件位置:fly_environment/model.config
<?xml version="1.0" ?>
<model><name>fly_environment</name> <!-- 模型名称 --><version>1.0</version> <!-- 版本 --><sdf version="1.7">model.sdf</sdf> <!-- 指定模型的 SDF 文件 --><author><name>Feng</name></author><description>This is a custom flying environment with obstacles.</description>
</model>
model.sdf
作用
- 作用:定义 模型的几何形状、物理属性、视觉效果,让 Gazebo 正确加载和模拟该模型。
- 主要包含:
- 模型名称
- STL 网格文件
- 物理属性(如碰撞、质量等)
- 视觉属性
- 坐标位置
``model.sdf
示例
文件位置:fly_environment/model.sdf
<?xml version="1.0"?>
<sdf version="1.10"><model name="fly_environment"><static>true</static> <!-- 设置为true,表示该模型不会移动 --><!-- 地面 --><link name="ground"><visual name="ground_visual"><geometry><mesh><uri>model://fly_environment/meshes/ground1.STL</uri></mesh></geometry></visual></link></model>
</sdf>
简介版的讲解如下:
如何打开stl文件加载出模型:首先导出dae文件,然后在终端nano model.config,nano model.sdf,分别编写这两个文件,注意的是,scale是指缩放比例(适用于自己建的模型),size是直接定义物体的尺寸(适用于gazebo自带的)
your_model/
│── model.config
│── model.sdf
│── meshes/
│ └── your_model.dae
│── textures/ (可选,存放纹理文件)
所有零件准备就绪后,开始盖房子,打造世界文件。
主控板px4学习:
-
基础配置:
-
烧录固件,可以多选择几个固件版本,观察哪个固件版本的效果最好,因为有些固件版本可能不适配导致一些奇奇怪怪的问题出现,比如电机无法正常驱动等,注意,烧录固件之后要重启
-
选择机架:选择符合自己机型的机架,然后重启
-
校准传感器:校准罗盘,加速度传感器,地平线等,注意校准之后要重启
-
校准遥控器:要注意遥控器的传输协议,有些老版本的飞控支持ppm协议,不支持pwm遥控器,要修改遥控器的配置,如果支持pwm遥控器的话正常连接就行了,跟随地面站的指示进行校准遥控器
-
飞行模式的选择:根据需要来就行了,如果不知道有哪些飞行模式可以选择,这是连接,但是要注意每种遥控器的设置会有所不同,下面是我的配置,大家需要注意遥控器的设置,以免踩坑。对了提一嘴遥控器的校准,打开遥控器,然后用镊子戳遥控器接收器的一个小按钮,等到遥控器的光不闪烁,常亮之后就行了。
- 校准电源:(注意这个时候不要装桨!!!),下图是我的配置,按自己的实际情况写好电池芯数,空点电压(一般是3.6),满电电压(一般是4.2),然后用万用表测试电池的电压写入电压分压器,然后重启飞控,然后用电流计测量实际电流,写入安培,然后重启飞控。
-
校准电调:本来主包也想省钱不买电流计的,后面发现不行,所以还是买了电流计,不然根本没办法校准电调,校准电调后,基本所有的前提条件都已经满足了。
-
在所有前提条件都测试完毕后,接上电源,地面站会显示就绪状态,如下图:
然后就可以将油门摇杆往右下方解锁无人机,调整油门控制无人机电机转速了。
-
-
无人机PID参数调试:
可能出现的问题及解决办法:
然后调pid的时候,一次只调一个轴向,控制变量要做好
快捷办法:其实也不一定需要调参,直接在地面站规划好航线,上传任务,然后让无人机自动起飞,一般都可以飞的很稳,不需要再继续调参了。
硬件组装
材料:
-
电调:通过飞控板给定的pwm波对电机进行调速,并且还具有给电机供电的作用,电陶的最大电流一定要保证高于电机的最大电流,不然会烧。
-
电机:电机上标的类似2205的数字,讲的就是直径22mm,高5mm,电机的kv值越高说明转速越快,如果求速度选择高kv值的,如果求稳定的选kv值低的像980kv。
-
桨叶: 如果追求高效率、长续航、高速 → 二叶桨(适合竞速无人机、巡航无人机)。
如果追求稳定性、低噪音、载重 → 三叶桨(适合摄影无人机、物流无人机)。
出于稳定性的考虑,在此处选择三叶桨
-
飞控:无人机的控制系统,相当于无人机的大脑。
-
分压板:电池与其他需电设备的桥梁,可以实现降压。
-
机架:使用solidworks 3D建模,然后打印出碳板
-
电池:一般用的是锂聚合电池,先解释一下参数的意思,s的意思是串联(意思是多个电池,电池的电流不变,但是电压可以积累),p的意思是并联,5300mA/h的意思是电池每小时放电5300mA,
常见的 S 数(电芯数)及对应电压:
1S = 3.7V(小型微型无人机)
2S= 7.4V(微型/入门级无人机)
3S= 11.1V(普通航拍机、竞速无人机)
4S= 14.8V(竞速无人机)
6S = 22.2V(高性能竞速/工业无人机)
12S = 44.4V(大型工业级无人机)
C是放电倍率,表示电池放电的最大电流能力,最大放电电流=C值×电池容量(Ah),比如4S 1500mAh 75C 电池 的最大电流就是:75C×(1500mAh/1000)=112.5A
- 小电脑:此处使用rdk×5,用于视觉方面的算法计算
- 深度相机:inter realsense t265
- 舵机:MG90s
无人机注意事项还有故障解决:
-
在上电前最好检查电池的容量,防止低压,然后充电的话要用专业充电器,一般采用普通模式充电,用低压模式保养。
-
在上电的时候,每个电机都是会定时转动一下的,这个是正常的,但是如果这个时候出现了电机无法正常转动的话,可以从一下几个地方排错:
电调供电虚焊(高概率):用万用表查看焊点的电压
**该通道 PWM 信号未输出(软件配置或排线问题):**打开qgc地面站,
电调本身损坏(小概率)
PX4的使用:
一:px4和其他软件的联动使用:控制逻辑(Python/C++)→ 发布 ROS 话题 → MAVROS → MAVLink → PX4飞控 → Gazebo模型运动
-
启动仿真:
cd ~/PX4-Autopilot make px4_sitl_default gazebo_iris__your_world
-
连接mavros:ROS2 节点能通过 MAVROS 接收/发送无人机数据
source /opt/ros/humble/setup.bash
source ~/ros2_ws/install/setup.bash
ros2 launch mavros px4.launch.py fcu_url:=udp://:14540@localhost:14557
- 启动qgroundcontrol:这个要用用线连接电脑端还有px4.
- 设置模式,既可以在qgroundcontrol中切换模式(不推荐),也可以在终端中使用命令
ros2 service call /mavros/set_mode mavros_msgs/srv/SetMode "{custom_mode: 'OFFBOARD'}"#注意这个要建立一个ros2_ws的新终端
-
解锁电机:
-
控制飞行,发布话题
#发送位置
ros2 topic pub /mavros/setpoint_position/local geometry_msgs/msg/PoseStamped ...#发送速度
ros2 topic pub /mavros/setpoint_velocity/cmd_vel geometry_msgs/msg/TwistStamped ...
或者也可以自己写一个文件实现无人机的自动起飞降落。
eg:
# offboard_square_flight.pyimport rclpy
from rclpy.node import Node
from geometry_msgs.msg import PoseStamped
from mavros_msgs.srv import CommandBool, SetMode
from mavros_msgs.msg import State
import timeclass SquareFlightNode(Node):def __init__(self):super().__init__('square_flight_node')# 当前状态变量self.state = State()self.current_pose = PoseStamped()# 发布位置指令self.local_pos_pub = self.create_publisher(PoseStamped, '/mavros/setpoint_position/local', 10)self.state_sub = self.create_subscription(State, '/mavros/state', self.state_cb, 10)self.pose_sub = self.create_subscription(PoseStamped, '/mavros/local_position/pose', self.pose_cb, 10)# 服务客户端:切换模式 / 解锁self.arming_client = self.create_client(CommandBool, '/mavros/cmd/arming')self.set_mode_client = self.create_client(SetMode, '/mavros/set_mode')# 等待服务可用while not self.arming_client.wait_for_service(timeout_sec=1.0):self.get_logger().info('等待 /cmd/arming 服务...')while not self.set_mode_client.wait_for_service(timeout_sec=1.0):self.get_logger().info('等待 /set_mode 服务...')# 飞行目标点(相对坐标系 NED)self.waypoints = [(0.0, 0.0, 2.0),(2.0, 0.0, 2.0),(2.0, 2.0, 2.0),(0.0, 2.0, 2.0),(0.0, 0.0, 2.0),]self.waypoint_index = 0self.reached = False# 定时器 10Hz 发布 setpointself.timer = self.create_timer(0.1, self.timer_callback)def state_cb(self, msg):self.state = msgdef pose_cb(self, msg):self.current_pose = msgdef timer_callback(self):# 初始化前先发一段 setpointif not self.state.armed:self.publish_setpoint(*self.waypoints[0])self.arm_and_set_mode()return# 计算是否到达目标点(误差阈值)target = self.waypoints[self.waypoint_index]pos = self.current_pose.pose.positiondist = ((pos.x - target[0]) ** 2 + (pos.y - target[1]) ** 2 + (pos.z - target[2]) ** 2) ** 0.5if dist < 0.3 and not self.reached:self.get_logger().info(f'到达航点 {self.waypoint_index + 1}')self.reached = Truetime.sleep(2.0) # 悬停 2 秒self.waypoint_index += 1if self.waypoint_index >= len(self.waypoints):self.get_logger().info('任务完成,保持悬停')returnelif dist >= 0.3:self.reached = False# 继续发布 setpointif self.waypoint_index < len(self.waypoints):self.publish_setpoint(*self.waypoints[self.waypoint_index])def publish_setpoint(self, x, y, z):pose = PoseStamped()pose.header.stamp = self.get_clock().now().to_msg()pose.pose.position.x = xpose.pose.position.y = ypose.pose.position.z = zself.local_pos_pub.publish(pose)def arm_and_set_mode(self):# 切换到 OFFBOARDif self.state.mode != "OFFBOARD":req = SetMode.Request()req.custom_mode = "OFFBOARD"self.set_mode_client.call_async(req)self.get_logger().info('尝试切换到 OFFBOARD 模式')# 解锁if not self.state.armed:req = CommandBool.Request()req.value = Trueself.arming_client.call_async(req)self.get_logger().info('尝试解锁无人机')def main(args=None):rclpy.init(args=args)node = SquareFlightNode()rclpy.spin(node)node.destroy_node()rclpy.shutdown()if __name__ == '__main__':main()
-
可视化rviz2:
ros2 run rviz2 rviz2
-
:二:飞行模式:从代码结构上分析,分为基本模式、自定义模式和自定义子模式
- 自定义模式分为,手动模式、高度控制模式、位置控制模式、自动模式、特技模式、自稳模式和外部模式。
手动模式----manual
高度控制模式----altctl
位置控制模式----posctl
自动模式----auto,在所有自定义模式中,只有auto模式有子模式,分别为 自动悬停、自动航点、自动返航、自动起飞、自动降落和自动跟随。
特技----acro
自稳模式----stabilized
外部模式----offboard:这是最主要的模式,无人机自动驾驶使用的就是这个方法,解锁飞控之后,用遥控器切换到offboard模式,向上位机发送节点,上位机就会把命令传输给px4,然后就会按照代码程序进行飞行 操作,关于这个过程中的通信问题
- 自定义模式分为,手动模式、高度控制模式、位置控制模式、自动模式、特技模式、自稳模式和外部模式。
上位机(此处使用的是rdk×5)的使用
-
官方手册:手册
-
简单的一个流程就是烧录镜像(系统默认是烧录的ubuntu22.04+ros2humble),装配各种驱动,缺啥装啥,比如深度相机(t265)的sdk还有源码,都需要下载好并且编译,microxrcedds-agent的下载及编译,tros的安装。
-
将深度相机连接在上位机上,注意:
- 不要热插拔,然后在通电的时候不要随意的插拔接口
- 如果要连显示屏的话,要先连接好hdml线,然后再通电),我一般使用的时ssh远程登陆,具体操作手册里面有,
- 要注意的是要保证供电正常,rdk的红灯和绿灯都要正常闪烁,然后要联网才可以连上ssh,如果连不上还有串口登陆等多种方式供选择
- 主包选择用vscode进行上位机的开发,下载一个叫做remote-ssh的插件,就可以用ssh远程登陆上位机了
- 如果rdk的板子坏了,可以选择抽出sd卡,将sd卡接入另一块好的rdk上,就可以正常使用了
-
深度相机的使用:在开始装驱动的时候,遇到了很多问题,最头疼的就是兼容性问题,t265的sdk最高支持版本是2.53,但是ros2控制深度相机源码的要求的最低sdk版本是2.56,所以就需要解决兼容性问题,不然colcon build会一直报错,主包的解决办法是修改realsense2_camera里的cmakelist.txt,搜索2.56,将2.56改成自己下载的版本,建议下载的是2.53版本,保存。然后
-
舵机的控制:用串口连接px4和rdk,然后就可以实现上位机与下位机的通信了。然后运行自己写的投放代码,就能实现物块投放功能了。
总体实机部署:
用ssh远程连接上位机,然后用串口将px4和上位机连接起来,用遥控器解锁无人机,将无人机模式切换到offboard,然后在终端启动程序,无人机就会按照代码的指令进行飞行,