Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/chapter/chap1/chap1.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

[进入小海龟画花瓣实验](turtle_sim_experiment.md)


### 6. 小海龟画五角星

使用发布器向`/turtle1/cmd_vel`话题发布速度指令,使用`/turtle1/set_pen`服务动态修改画笔RGB颜色,实现彩色绘图,通过定时方式控制海龟直行距离与旋转角度,完成五角星轨迹绘制,使用`rosnode`、`rostopic`、`rosservice`工具查看节点、话题、服务,验证ROS通信。
Expand All @@ -58,4 +59,5 @@
结合 `/turtle1/pose` 的位姿反馈、`/turtle1/cmd_vel` 的速度控制和 `/turtle1/set_pen` 的画笔服务,
控制小海龟把输入的文字逐笔绘制在画布上。

[进入小海龟绘制任意文字实验](turtle_text.md)
[进入小海龟绘制任意文字实验](turtle_text.md)

115 changes: 115 additions & 0 deletions docs/ground/task1_autonomous_car.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
无人车物理仿真与键盘控制

本文档介绍如何在 OpenHUTB 2.10.0 (Gazebo) 仿真环境中,实现 3D 无人车的物理仿真。通过自定义的 ROS 节点(main.py),将键盘输入与仿真器控制进行解耦,利用 /cmd_vel 话题(geometry_msgs/Twist)实现消息层面的运动控制。

1. 算法原理与流程

1.1 运动学模型与计算公式

无人车采用差速驱动模型。运动控制指令(geometry_msgs/Twist)包含线速度 $v$ 和角速度 $\omega$,据此可计算车轮的目标角速度。
设左右轮角速度为 $\omega_L, \omega_R$,轮半径为 $r$,两轮间距为 $L$,则正运动学方程为:

$$ \omega_L = \frac{v - \frac{\omega L}{2}}{r} $$

$$ \omega_R = \frac{v + \frac{\omega L}{2}}{r} $$

1.2 控制流程

本任务采用手动控制作为基准测试,通过按键映射直接发布速度指令。

```mermaid
graph LR
A[键盘按键 W/A/S/D] -->|终端标准输入| B(main.py 节点)
B -->|计算线速度与角速度| C{生成 Twist 消息}
C -->|发布 /cmd_vel 话题| D[Gazebo 物理引擎]
D -->|差速驱动控制| E[TurtleBot3 无人车]
```

2. 仿真环境搭建与操作步骤

2.1 环境依赖

· 操作系统:Ubuntu 20.04
· ROS 版本:ROS Noetic
· 仿真引擎:Gazebo 11
· 机器人模型:TurtleBot3 (Burger)

2.2 启动仿真世界

1. 打开第一个终端,启动 ROS 核心服务:
```shell
source /opt/ros/noetic/setup.bash
roscore
```
2. 打开第二个终端,启动包含无人车的 Gazebo 物理仿真环境:
```shell
source /opt/ros/noetic/setup.bash
export TURTLEBOT3_MODEL=burger
roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch
```
【操作截图】:启动成功后,在弹出的 Gazebo 窗口中央可以看到 3D 无人车模型,地面网格清晰可见。
![键盘遥控无人车仿真演示](../img/task1_demo.gif)

2.3 启动自定义控制节点

打开第三个终端,使用 launch 文件启动我们自己编写的 main.py 节点:

```shell
source ~/hutb_ws/devel/setup.bash
roslaunch hutb_robot task1_keyboard.launch
```

3. 源代码解析

核心节点 main.py 的代码逻辑解析:

· 键盘监听:使用 termios 与 tty 库,设置终端为原始模式(tty.setraw),实现不按回车即可实时捕获按键。
· 消息发布:创建 rospy.Publisher('/cmd_vel', Twist, queue_size=1),在 10Hz 的循环中,根据按键状态修改 Twist.linear.x 和 Twist.angular.z 的值。
· 异常保护:使用 try...finally 结构,确保程序退出前发布全 0 的速度指令,防止小车失控冲撞。

4. 运行效果与演示
![键盘遥控无人车仿真演示](../img/task1_demo.gif)
4.1 键盘键位映射

按键 功能 速度指令 计算公式/说明
W 前进 linear.x = 0.2 m/s 结合公式1.1转化为车轮转速
S / 空格 停止 linear.x = 0.0 所有速度置零
X 后退 linear.x = -0.2 m/s 速度方向取反
A / D 左转/右转 angular.z = ±1.0 rad/s 改变左右轮转速差

4.2 演示动图 (GIF)

![键盘遥控无人车仿真演示](../img/task1_demo.gif)

5. 多场景测试与性能评价

5.1 场景测试

· 场景1 (空世界):测试小车的基本运动学物理特性,验证运动解算无误。小车在平坦地面上按指令正常前进与转向。
· 场景2 (复杂障碍物场景):在 turtlebot3_house 等包含墙壁与杂物的场景中测试手动避障的灵活性。由于手动控制存在延迟,节点成功实现了速度的平滑过渡,未发生严重碰撞。

5.2 性能评价

· 控制延迟:键盘输入到 Gazebo 画面响应的物理延迟极低(<100ms),满足仿真测试要求。
· 稳定性:在 10Hz 的发布频率下,小车运动平稳,没有出现控制指令拥堵或超时问题。

6. 常见问题排查 (Troubleshooting)

· 问题:输入 roslaunch 报错 Command 'roslaunch' not found。
· 解决:未加载 ROS 环境变量。请确保执行 source /opt/ros/noetic/setup.bash。
· 问题:按键后小车不动,但终端有输出。
· 解决:确认是否启动了正确的 Gazebo 世界,并检查 /cmd_vel 话题是否被正确订阅(可用 rostopic echo /cmd_vel 排查)。
· 问题:Python 脚本无执行权限。
· 解决:进入脚本目录执行 chmod +x main.py。

7. 后续演进 (任务2-4预告)

当前任务(1)采用手动键盘控制作为物理仿真的基准验证。在接下来的任务(2)、(3)、(4)中,将引入深度神经网络 (CNN) 替代键盘输入,实现:

1. 基于摄像头图像的端到端(端到端模型)控制。
2. 基于强化学习的自主建图与导航(SLAM)。
3. 实现多场景下的自主避障与路径规划。

(注:后续将补充神经网络模型结构计算公式与算法流程图)

---
Binary file added docs/img/car.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/task1_demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ ROS每章节运行代码:
* [扭转控制](./ground/twist_to_control.md)
* [RQT 插件](./ground/rqt_plugin.md)
* [点云地图创建](./ground/pcl_recorder.md)
* [无人车物理仿真与键盘控制](./ground/task1_autonomous_car.md)
* [车辆键盘遥操作与二维模拟](./ground/vehicle_pygame_teleop.md)


## 5. 空域载具 <span id='air_vehicle'></span>

* [无人机飞行轨迹类型识别与 ROS2 自动任务日志](./air/flight_pattern_recognition.md)
Expand Down
7 changes: 7 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ nav:
- 地面载具:
- 手动控制: './set_up_and_connect_to_carla.md'
- 生成对象: './ground/carla_spawn_objects.md'
- 无人车物理仿真与键盘控制: 'ground/task1_autonomous_car.md'
- 地面载具物理仿真与键盘运动控制: './ground/carla_keyboard_control.md'
- 阿克曼控制: './ground/ackermann_control.md'
- 路径点发布器: './ground/waypoint.md'
Expand Down Expand Up @@ -120,8 +121,14 @@ markdown_extensions:
- footnotes
- admonition
- mdx_math
- pymdownx.arithmatex:
generic: true
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:mermaid2.fence_mermaid

extra_javascript:
- https://polyfill.io/v3/polyfill.min.js?features=es6
- https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
14 changes: 14 additions & 0 deletions src/ground/autonomous_car/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.0.2)
project(autonomous_car)

find_package(catkin REQUIRED COMPONENTS
rospy
geometry_msgs
)

catkin_package()

# 告诉 catkin 把 main.py 安装为可执行程序(因为你的 main.py 直接放在根目录下)
catkin_install_python(PROGRAMS main.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
9 changes: 9 additions & 0 deletions src/ground/autonomous_car/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# 任务1:无人车物理仿真与键盘控制
## 运行环境
Ubuntu 20.04 + ROS Noetic + Gazebo 11
## 运行步骤
1. `roscore`
2. `roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch`
3. `roslaunch autonomous_car task1_keyboard.launch`
## 效果演示
![demo](../../docs/img/task1_demo.gif)
52 changes: 52 additions & 0 deletions src/ground/autonomous_car/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import rospy
from geometry_msgs.msg import Twist
import sys, select, termios, tty

msg = """
控制你的小车!
---------------------------
移动:
w
a s d
x
w/x : 增加/减少线速度
a/d : 增加/减少角速度
空格/S : 强制停止
CTRL-C 退出
"""

def getKey():
tty.setraw(sys.stdin.fileno())
select.select([sys.stdin], [], [], 0)
key = sys.stdin.read(1)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
return key

if __name__=="__main__":
settings = termios.tcgetattr(sys.stdin)
rospy.init_node('hutb_keyboard_control')
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
speed = 0.2
turn = 1.0
x = 0; th = 0
try:
print(msg)
while(1):
key = getKey()
if key == 'w' : x = speed; th = 0
elif key == 'x' : x = -speed; th = 0
elif key == 'a' : x = 0; th = turn
elif key == 'd' : x = 0; th = -turn
elif key == ' ' or key == 's' : x = 0; th = 0
elif key == '\x03': break
twist = Twist()
twist.linear.x = x; twist.angular.z = th
pub.publish(twist)
except Exception as e:
print(e)
finally:
twist = Twist()
pub.publish(twist)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
15 changes: 15 additions & 0 deletions src/ground/autonomous_car/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<package format="2">
<name>autonomous_car</name>
<version>0.0.1</version>
<description>The autonomous_car package for Task 1</description>
<maintainer email="user@todo.todo">user</maintainer>
<license>TODO</license>

<buildtool_depend>catkin</buildtool_depend>
<build_depend>rospy</build_depend>
<build_depend>geometry_msgs</build_depend>

<exec_depend>rospy</exec_depend>
<exec_depend>geometry_msgs</exec_depend>
</package>
3 changes: 3 additions & 0 deletions src/ground/autonomous_car/task1_keyboard.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<launch>
<node name="hutb_keyboard_main" pkg="autonomous_car" type="main.py" output="screen"/>
</launch>