准备工具
ubuntu18.04
gazebo
PX4+ROS环境配置
xtdrone配置
多无人机仿真
roslaunch px4 multi_uav_mavros_sitl.launch
xtdrone上给出的多无人机启动launch文件,其中默认有三个飞行器,分别为uav0,uav1,uav2
其中的无人机编号代码部分为
可以 增加无人机在文件最后添加一个组即可(复制以上)
其中要修改的有
<group ns="uav3">
这是命名无人机 ,也是修改话题,服务前缀.
<arg name="ID" value="3"/>
<arg name="fcu_url" default="udp://:24543@localhost:34583"/>
这是无人机ID参数和通信接口,与上一架飞机同参数增加一即可.
其次还有这些,mavlink通信port
<arg name="mavlink_udp_port" value="18573"/>
<arg name="mavlink_tcp_port" value="4563"/>
还有一处
<arg name="x" value="1"/>
<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"/>
这里可以改变飞行器初始位置,如果不改的话会和上一个无人机重叠.
这样就添加了一架无人机
可以随意增加(只要你的电脑内存足够)
像这样
是不是很壮观!
查看话题,服务列表后会出现带前缀的
无人机键盘控制
首先我这里参考了这位博主的文章
https://blog.csdn.net/cherish1211/article/details/131951664?spm=1001.2014.3001.5502
该博主是在pycharm上编译运行的,我这里要修改一下.
让这个节点在ROS下编译,代码如下
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import mavros_msgs
import rospy
from mavros_msgs.srv import SetMode,CommandBool
import sys, select, os
#os模块是用于与操作系统进行交互的模块。TTY(teletypewriter)是指终端设备,例如终端窗口、终端控制台或串口终端。
#select 模块:该模块提供了对低级 I/O 多路复用的支持。
#termios模块是Python中用于处理终端IO(Input/Output)的模块,允许我们控制终端的特性(attributes),例如字符的读取方式、输入输出模式等。
import tty, termios
from std_msgs.msg import String
msg2all = """
请输入输入指令:
r : return home
t/y : arm/disarm
v/n : takeoff/land
b : offboard
p : position
s : stabilized
k : hover and remove the mask of keyboard control
CTRL-C to quit
"""
def getKey():
#这行代码使用tty模块的setraw()函数来设置标准输入(sys.stdin)的行为为原始模式。
#原始模式下,输入不经过缓冲,每次输入一个字符。
tty.setraw(sys.stdin.fileno())
#这行代码使用select模块的select()函数来检查是否有可读取的数据。
#它监视sys.stdin(标准输入),并且等待0.1秒钟。如果在等待期间有数据可读,
#则select()函数会返回一个非空的可读列表(rlist),否则返回空列表
rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
#这段代码检查rlist列表是否非空。如果列表非空,说明在等待期间有数据可读。
#此时,通过sys.stdin.read(1)读取一个字符,并将其赋值给key变量。
#如果列表为空,则说明在等待期间没有数据可读,此时将key变量赋值为空字符串。
if rlist:
key = sys.stdin.read(1)
else:
key = ''
#这行代码使用termios模块的tcsetattr()函数来恢复标准输入的设置。
#TCSADRAIN参数表示在所有排队的输出都被传输和处理之后才生效。
#将标准输入的属性设置为之前保存的settings值。它使用termios.tcsetattr函数来设置终端的属性。
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
#最后,函数返回变量key的值,即读取到的字符(如果有)或空字符串(如果没有读取到字符)。
return key
def print_msg():
print(msg2all)
#主函数
if __name__=="__main__":
#设置终端为标准输入流
settings = termios.tcgetattr(sys.stdin)
rospy.init_node('my_keyboard_control')
uav_cmd_pub = rospy.ServiceProxy("/mavros/set_mode",SetMode)
uav_arm_pub=rospy.ServiceProxy("/mavros/cmd/arming",mavros_msgs.srv.CommandBool)
#uav_cmd_pub = rospy.ServiceProxy("/uav_0/mavros/set_mode",SetMode)
#uav_arm_pub = rospy.ServiceProxy("/uav_0/mavros/cmd/arming",mavros_msgs.srv.CommandBool)
print_msg()
cmd=""
while(1):
key = getKey()#获取读取到的字符
if key == 'r':
cmd = 'AUTO.RTL'
print_msg()
print('Returning home')
elif key == 't':
cmd = 'ARM'
print_msg()
print('Arming')
elif key == 'y':
cmd = 'DISARM'
print_msg()
print('Disarming')
elif key == 'v':
cmd = 'AUTO.TAKEOFF'
print_msg()
#print('Takeoff mode is disenabled now')
elif key == 'b':
cmd = 'OFFBOARD'
print_msg()
print('Offboard')
elif key == 'n':
cmd = 'AUTO.LAND'
print_msg()
print('Landing')
elif key == 'p':
cmd = 'POSCTL'
print_msg()
print('Position')
elif key == 's':
cmd = 'STABILIZED'
print_msg()
print('Stabilized')
elif key in ['k']:
cmd = 'HOVER'
print_msg()
print('Hover')
elif(key == '\x03'):
break
if (cmd=='ARM'):
uav_arm_pub(True)
elif (cmd=='DISARM'):
uav_arm_pub(False)
else:
uav_cmd_pub(custom_mode=cmd)
cmd = ''
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
我添加了ROS中python文件的表头,然后增加了两种模式,自稳和悬停模式
然后通过ros节点即可运行
rosrun offboard_nodes key_board.py
记得退出虚拟环境,不然会报错的.
先按t键解锁无人机,再切offboard即可.
多无人机键盘控制
我在上述代码中增加了1-9按键的控制,分别对应1-9号无人机.
添加如下代码
uav_name = 'uav0'
uav_cmd_pub = rospy.ServiceProxy(uav_name+"/mavros/set_mode",SetMode)
uav_arm_pub=rospy.ServiceProxy(uav_name+"/mavros/cmd/arming",mavros_msgs.srv.CommandBool)
...
if key == '1':
uav_name = 'uav0'
print("开启无人机一号")
elif key == '2':
uav_name = 'uav1'
print("开启无人机二号")
...
分别是添加话题的前缀,,然后增加数字按键的读取,改变前缀名称.
注:这里前缀名称和你前面launch文件中定义的无人机名称一致,才能控制.
视频效果如下
GAZEBO多无人机通信仿真(键盘控制)