实验室买来方向盘用作二次开发,但是并没有相关的驱动,我们需要用cpp或是Python实现方向盘的驱动,获得方向盘的输出,再传给下位机等。
方向盘本质上还是游戏手柄,通过查游戏手柄的驱动我们发现专业术语叫joysticker
,因此意外在linux内核网站里找到这样一个api可以直接通过访问硬件借口获得USB方向盘的输出。
api地址:https://www.kernel.org/doc/Documentation/input/joystick-api.txt
api首先访问linux的硬件端口/dev/input/js0
,然后找到axis和button的地址,做一个映射取到value。
因为我们只关注踏板和转盘,所以只在乎对axis的操作。
对api做了如下修改,得到方向盘转动角度和踏板转动角度的值axis
# Released by rdb under the Unlicense (unlicense.org)
# Based on information from:
# https://www.kernel.org/doc/Documentation/input/joystick-api.txt
import os, struct, array
from fcntl import ioctl
# Iterate over the joystick devices.
print('Available devices:')
for fn in os.listdir('/dev/input'):
if fn.startswith('js'):
print(' /dev/input/%s' % (fn))
#这句显示手柄在硬件中的端口位置: /dev/input/js0
# We'll store the states here.
axis_states = {}
button_states = {}
#先前校验时,方向盘是x,左侧踏板是z,右侧踏板是rz。
# These constants were borrowed from linux/input.h
axis_names = {
0x00 : 'x',
0x02 : 'z',
0x05 : 'rz',
}
axis_map = []
# Open the joystick device.
fn = '/dev/input/js0'
print('Opening %s...' % fn)
jsdev = open(fn, 'rb')
# # Get the device name.
buf = array.array('u', ['\0']*5)
ioctl(jsdev, 0x80006a13 + (0x10000 * len(buf)), buf) # JSIOCGNAME(len)
js_name = buf.tostring()
print('Device name: %s' % js_name)
# Get number of axes and buttons.
buf = array.array('B', [0])
ioctl(jsdev, 0x80016a11, buf) # JSIOCGAXES
num_axes = buf[0]
# Get the axis map.
buf = array.array('B', [0] * 0x40)
ioctl(jsdev, 0x80406a32, buf) # JSIOCGAXMAP
#
for axis in buf[:num_axes]:
axis_name = axis_names.get(axis, 'unknown(0x%02x)' % axis)
axis_map.append(axis_name)
axis_states[axis_name] = 0.0
# Main event loop
while True:
evbuf = jsdev.read(8)
if evbuf:
time, value, type, number = struct.unpack('IhBB', evbuf)
if type & 0x02:
axis = axis_map[number]
if axis:
#print("{}".format(axis))
if axis=="x":
fvalue = value / 32767
axis_states[axis] = fvalue
print ("%s: %.3f" % (axis, fvalue))
if axis == "z":
#print(value)
if value<0:
fvalue = value / 32767
axis_states[axis] = fvalue
print ("%s: %.3f" % (axis, ( (fvalue+1)/2)))
elif value>0:
fvalue = value / 32767
axis_states[axis] = fvalue
print ("%s: %.3f" % (axis, ( (fvalue+1)/2)))
if axis == "rz":
#print(value)
if value<0:
fvalue = value / 32767
axis_states[axis] = fvalue
print ("%s: %.3f" % (axis, ( (fvalue+1)/2)))
elif value>0:
fvalue = value / 32767
axis_states[axis] = fvalue
print ("%s: %.3f" % (axis,( (fvalue+1)/2)))
转动方向盘或是踏下踏板得到如下结果。
CPP版本及Linux驱动脚本可以参考:[joysticker]使用Ubuntu读取USB手柄/方向盘的输出控制