继续树莓派小车的内容,这次记录手柄控制小车运动的实现。
1 方案设计
对于手动控制小车的工具,大概有这么几种:
①用红外遥控器,小车上放一个接收器,读取遥控器信息。实现应该比较简单,红外收发元件也很便宜,不过遥控器得对着小车,恐怕不太方便;
②蓝牙手柄,因为树莓派带蓝牙,可以通过蓝牙接收手柄数据,不过一个蓝牙手柄可不便宜;
③有线手柄,相比无线设备肯定low一点,不过我手头就只有一个有线手柄,50多块钱的小鸡G3,就是个xbox 360手柄;
④手机,如果写个带方向键的手机客户端来控制小车应该是最酷的了,不过我不会Android或IOS开发。
最终选择用有线手柄控制小车,而控制方式不是把手柄连到树莓派上,而是连到我的笔记本上,用C#写个客户端程序,一方面读取手柄数据,一方面与树莓派通信。至于通信,采用TCP通信,树莓派上运行服务器程序,接收控制信息,电脑上运行客户端程序,发送手柄数据。
2 手柄数据读取
现在主要的问题是怎么读取手柄数据呢?通过网络搜索,发现可以使用SharpDX库在.NET平台下读取手柄输入数据,SharpDX是一个全新的、开源的、封装了 DirectX API的项目(Wiki文档链接:http://sharpdx.org/ ,目前还不全),其支持的API包括2D和3D渲染、音频、设备输入等方面,貌似游戏开发中使用的挺多的。不过我不需要用到那么多功能,只需要使用XInput库就行,XInput支持XBox360手柄的数据读取。关于SharpDX及XInput的教程或文档有点难找,Wiki上的官方文档只是接口说明,而且现在还不全;微软官方文档上可以找到XInput的相关文档,不过它是针对C++的;我在Stack Overflow找到一个回答,介绍了SharpDX.XInput的简单使用方法(https://stackoverflow.com/questions/39109609/how-to-use-xbox-one-controller-in-c-sharp-application/39109610#39109610)。
首先需要下载SharpDX.XInput库,可以在Visual Studio的Nuget包管理器里直接下,不过如果直接下SharpDX.XInput会提示需要依赖SharpDX库,因此先下SharpDX库。下好SharpDX后再下载SharpDX.XInput竟然还是报错,说缺少SharpDX依赖,这时可以先卸载Nuget管理器再重安装(“工具”->“扩展和更新”),这样就可以顺利下载了。
添加XInput的引用using SharpDX.XInput;
,然后可以写一个手柄控制类:
class XInputController
{
Controller controller;
Gamepad gamepad;
public bool connected = false;
public XInputController()
{
controller = new Controller(UserIndex.One);
connected = controller.IsConnected;
}
/// <summary>
/// 读取方向键信息
/// </summary>
/// <returns></returns>
public string GetDirection()
{
if (!controller.IsConnected)
return null;
gamepad = controller.GetState().Gamepad;
GamepadButtonFlags flag = gamepad.Buttons