目录
模拟实验
双帆船的帆机通过绳索与两个帆连接,帆的实际角度会受到风的影响,在0度和帆机输出到角度之间。在模拟过程中假定帆的实际角度就是帆机输出的角度。
1. 启动图形化界面
打开一个新终端,运行以下命令,启动第一个 ROS 节点。
roslaunch sailboat_launch start_tf_tree_onboat.launch
如果没有报错,Ctrl+Alt+T 打开新终端,运行以下命令,启动第二个节点。
roslaunch spare_function spare_function_simulation.launch
如果没有报错,Ctrl+Alt+T 打开新终端,进入 simulation 文件夹下。此目录需要根据自己安装的目录做修改,可能是这样:
cd ~/sailboat_ws/src/Sailboat-Ros/Sh/simulation
也可能是这样:
cd ~/sailboat_ws/src/2019-sailboat-ros/Sailboat-Ros/Sh/simulation
命令 cd 代表进入某目录,紧接着 ~/ 表示 “home/你的用户名” 这个目录。总之,目录需要自己根据实际状况修改。也可以使用鼠标和图形化界面手动打开 simulation 文件夹,然后鼠标右键选择打开新终端。
进入 simulation 文件夹后,运行文件夹中的 interface.sh 脚本文件。命令如下:
./interface.sh
等待几秒钟后,将会陆续启动 rviz 和 rqt 两个应用程序。左边的任务栏中可以看到 rviz 的文字图标和九个蓝点的 rqt 图标。
在 rviz 中点击相应的选项可以显示帆船的路径。
在 rqt 中勾选相应的复选框并展开对应的话题,可以观察帆船当前的输入和输出。
2. 运行 python 文件
最后需要启动自己为帆船写的程序,用于输出帆和舵的角度。
cd ~/sailboat_ws/src/2019-sailboat-ros/Sailboat-Ros/Class/spare_function/scripts
python example.py
同样,目录需要根据自己 python 文件的位置决定。上述命令中的 example.py 是示例代码,输出的帆和舵的角度始终为0度。自己编写帆船程序后需要使用 python 命令运行自己的 python 文件。如果在运行 python 文件时有报错,请根据提示检查自己写的 python 文件对应行存在的问题。
3. 调试
如果你的 python 文件没有报错,说明程序在语法上通过了编译,接下来需要检查在逻辑上是否存在问题,帆船是否可以按照预期行驶。这时需要借助 rviz 观察帆船的路径,通过 rqt 观察输出的数据。通过调整动态参数检查是否所有情况下都可以正常运行。
如何自定义 rqt 中显示的数据,以及如何调整动态参数(或者说,动态参数是什么),将在下一章详解。
python 文件与 rqt 的关系
python 文件的位置:
~/sailboat_ws/src/2019-sailboat-ros/Sailboat-Ros/Class/spare_function/scripts
1. 获取传感器数据
设计帆和舵的控制策略时,需要传感器数据。文件在开头导入了传感器消息文件 Sensor_msg。
from sailboat_message.msg import Sensor_msg
随后,程序在第三个函数中使用了传感器数据。
def sensorCallback(msg): #sailboat_message::Sensor_msg
global sensor_submsg
sensor_submsg[0] = msg.Roll
sensor_submsg[1] = msg.Yaw
sensor_submsg[2] = msg.AWA
这个函数参数 msg 是从 ROS 订阅得到的,我们可以在主函数中看到函数的调用:
rospy.Subscriber("sensor", Sensor_msg, sensorCallback)
回到第三个函数,传感器数据文件位于
~/sailboat_ws/src/2019-sailboat-ros/Sailboat-Ros/Message/sailboat_message/msg
打开这个文件,我们可以看到传感器数据有这些:
Header header
float64 ux
float64 vy
float64 wz
float64 gx
float64 gy
float64 gz
float64 Posx # x 坐标
float64 Posy # y 坐标
float64 PosZ # z 坐标
float64 Roll # 横摇角
float64 Pitch # 纵摇角
float64 Yaw # 艏向角
float64 AWA # 相对风向角
float64 AWS # 相对风速
float64 TWA # 绝对风向角,可能不完全正确,最好自己计算
float64 TWS # 绝对风速
在示例文件 example.py 中,sensorCallback 函数只使用了其中的三个数据 (Roll, Yaw, AWA),如果我们需要其它传感器数据,就将需要的值在 sensorCallback 函数中赋值给全局变量数组 sensor_submsg,然后修改程序开头全局变量数组的长度。例如,我希望使用相对风速 AWS,应当这样做:
sensor_submsg = [0,0,0,0]
def sensorCallback(msg): #sailboat_message::Sensor_msg
global sensor_submsg
sensor_submsg[0] = msg.Roll
sensor_submsg[1] = msg.Yaw
sensor_submsg[2] = msg.AWA
sensor_submsg[3] = msg.AWS
这样,主函数需要使用 AWS 时,只需调用全局变量 sensor_submsg[3] 即可。
2. 将数据输出到 rqt
如果希望将一些自己定义的数据输出到 rqt 以方便调试,那么需要修改文件 spare_function_out.msg,文件目录如下
/sailboat_ws/src/2019-sailboat-ros/Sailboat-Ros/Class/spare_function/msg
打开文件后,可以看到目前里面只有帆和舵的数据
float64 sail
float64 rudder
如果我们在主函数中自己定义了一个名称为 is_tacking 的布尔变量,来判断帆船当前处于顺风状态还是逆风,需要将 spare_function_out.msg 文件修改为
float64 sail
float64 rudder
bool is_tacking_publish
此外,还需要将自己写的 python 程序,例如 example.py 的主函数改为
try:
while not rospy.is_shutdown():
mach_np = [ra, sa, 1]
out_np = [ra, sa, is_tacking]
#para_np = [0,0,0,0,0,0,0]