上一篇文章介绍了用web界面来控制小车移动,这篇文章介绍用蓝牙游戏手柄来控制小车的移动。物理手柄的控制会更加得心应手,不会受网络延迟的影响。
1. 蓝牙游戏手柄
笔者使用的一款价格约100元的小鸡蓝牙手柄,理论上所有带蓝牙功能的手柄都支持,如PS3, Xbox One等等。
1.2 手柄配置
不管什么型号的手柄,一般都有相似的功能按钮,分为以下两类:轴和按钮。
轴(axis):
能输出连续变化的值,如:
- L2, R2是根据按压的力度输出从0~32767的值;
- 左右摇杆(left_stick, right_stick)是输出两个方向从-32767~32767的值:up_down、left_right,摇杆不动(居中)的值是0。
按钮(button):
只有0或1的值,按下去为1。如D Pad的上下左右4个按钮,L1, R1;L2和R2也能同时输出是否被按下。
从手柄设备的设备文件(如/dev/input/js0
)可以读出手柄的控制信号,信号包含操作的按钮/轴和它的值。按钮/轴由一个16进制的数字来标识。不同厂商/型号的手柄的数字标识是不一样的,需要在配置文件指定。如config/joystick_drive.yml
里的配置就是我的小鸡手柄G3的映射值。
Joystick
类定义了通用的按钮名,你只需要配置不同按钮的标识就可以了。
joystick:
axis_keys:
'left_stick_horz': 0x00 # 左摇杆的水平方向
'left_stick_vert': 0x01 # 左摇杆的垂直方向
'right_stick_horz': 0x02
'right_stick_vert': 0x05
'dpad_leftright': 0x10 # 方向按键的左右方向
'dpad_up_down': 0x11 # 方向按键的上下方向
'L2_pressure': 0x0a # L2的按压压力
'R2_pressure': 0x09 # R2的按压压力
button_keys:
'select': 0x13a # 选择键
'start': 0x13b # 开始键
'L1': 0x136
'R1': 0x137
'L2': 0x138
'R2': 0x139
'left_stick_press': 0x13d # 左摇杆被按下
'right_stick_press': 0x13e # 右摇杆被按下
'A': 0x130
'B': 0x131
'X': 0x133
'Y': 0x134
自己的手柄连上电脑后,可以到https://html5gamepad.com/这个网站检测自己的手柄的按键。然后写到配置文件就可以了。
1.3 按键功能
我们控制小车不需要用完上面的全部按键。源码中的Joystick
类给不同的按钮/轴绑定了对小车做不同的操作。具体有:
- 左摇杆水平方向(
left_stick_horz
):控制小车的左右转向(steering
)。 - 右摇杆的竖直方向(
right_stick_vert
):控制小车的前进和后退(throttle
)。 - Y: 切换自动驾驶/手动驾驶模式
- B: 切换录像开/关
- L1: 降低最高速度
- R1: 提高最高速度
其他按键暂时没有用到,可以留作以后扩展更多功能。你也可以修改配置文件来绑定不同的按键。
1.4 代码实现
jetson nano连上蓝牙手柄会产生一个设备文件,如/dev/input/js0
,我们不断读取该文件,解析读到的指就可以了。部分代码参考了donkeycar的controller文件。
控制信号会发送到CAN
,actuator
和其他订阅者就能作出反应了。本次完整的配置文件如下(config/joystick_drive.yml
):
2. 录制视频
本次文章篇幅不长,我们顺便实现录制视频的功能,同样比较简单,只需要使用cv2.VideoWriter
类把摄像头的图像逐帧写入文件就可以了。
writer = cv2.VideoWriter(file_name,
cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'),
frame_rate,
(width, height))
writer.write(frame)
默认VideoRecorder
类会保存一个capture.avi
文件到当前目录。也可通过配置文件指定路径和文件名,还有分辨率、帧率。见上一章节的video_recorder
配置。
3. 运行
文章的代码已经开源到github mycar项目。
3.1 clone代码
git clone https://github.com/evan-wu/mycar
git checkout -b blog-4
3.2 连接蓝牙手柄
把手柄打开,进入蓝牙配对模式,然后在jetson nano的蓝牙设置点+号找到手柄,连接上就可以了。以下是我的蓝牙手柄:
连接上以后可以查看一下对应的设备文件:
$ file /dev/input/js0
/dev/input/js0: character special (13/0)
3.3 启动
cd mycar
bin/run.sh config/joystick_drive.yml 120
可以使用手柄来控制小车移动了,按B
可以开始录像!
后续预告:视觉PID循线算法。敬请期待!
欢迎blog/github点赞,评论,讨论!