Thrustmaster Hotas Warthog飞行操作杆开发

news/2025/1/16 18:19:33/

目录

0  摘        要         :简单说一下这篇文章在搞啥

1  背        景         :什么需求以及对开发的背景调查

2  环境配置          :具体需要什么环境,对软件层面的需求

3  硬件测试          :测试遥感器硬件本身好坏以及是否正常连接

4  Debug              :软件debug并放出相关代码

6  后       续          :完结撒花


0摘要

       本文主要介绍了一个简单的demo。在windows下通过DirectInput开发套件读取Thrustmaster Hotas Warthog飞行操作杆数据,要求后续可能会用C++进行更加深入的二次开发。


1背景

        今天上午,同事给我布置了一个任务,让我读取一个遥感的数据,要求后面用C++进行二次开发,看了一下设备,是:A10C疣猪双手摇杆 – Thrustmaster(图马思特)

        首先我去了官网,大致浏览了一番,发现官网没有说到相关素材的。只有适配什么软件啊,说明书啊,没有提到怎么进行二次开发,可惜...... 有幸在CSDN上找到几篇相关的内容,但是都不能直接解决我的二次开发问题,有的虽然有重合,但是需要收费。这里一次放出:

首先是python的,参考博客:Thrustmaster(图马思特) HOTAS Warthog 疣猪杆 读取按钮数据-CSDN博客

然后是介绍如何在Windows下通过Directinput来开发(收费):

Thrustmaster Hotas Warthog/猪杆/疣猪飞行操作杆开发_疣猪摇杆-CSDN博客

还有一个是使用XInput开发的,本人试过了可以使用,但是这个开发工具存在问题,简单的调试可以,但是如果是游戏那种对实时性要求高的就不行了:
Thrustmaster HOTAS Warthog 开发指南-CSDN博客

别人的实例代码:

#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>#pragma comment(lib,"Winmm.lib")int main()
{UINT inum = joyGetNumDevs();printf("%d\n", inum);while (getchar() != 'q'){UINT uJoyID = 0;LPJOYINFO pji = new joyinfo_tag;joyGetPos(uJoyID, pji);printf("pji->wXpos: %d\n", pji->wXpos);printf("pji->wYpos: %d\n", pji->wYpos);printf("pji->wZpos: %d\n", pji->wZpos);printf("pji->wButtons: %d\n", pji->wButtons);}return 0;
}

2环境配置

        那就麻烦万能的GPT了

我:有一个Thrustmaster hotas warthog摇杆,怎么做二次开发?

ChatGPT 说:

要对Thrustmaster HOTAS Warthog摇杆进行二次开发,可以从以下几个方面入手:

1. 了解设备接口

HOTAS Warthog通常通过USB接口与PC连接,符合HID(Human Interface Device)标准。

可使用HID协议或现成的库读取和控制设备。

2. 开发工具与库

  • DirectInput/XInput:Windows平台上读取输入设备的API。适合处理复杂输入设备。
  • vJoy:虚拟摇杆驱动,适合自定义输入信号。
  • HIDAPI:跨平台库,可直接与HID设备通信。
  • Joystick Gremlin:用于自定义摇杆输入和映射(适合无代码修改)。
  • Python:利用pyvjoy或pyhidapi库开发自定义功能。

3. 固件/硬件层开发

  • HOTAS Warthog固件不可直接修改,但可以通过外接设备(如Arduino或STM32)中转信号,实现高级功能。
  • 如果想进行深度硬件改造,可以拆解摇杆并改装开关或传感器。

4. 软件集成

  • DCS World或Microsoft Flight Simulator等模拟飞行游戏支持自定义插件开发,可与摇杆联动。
  • 使用Lua脚本或SDK对接游戏,实现更复杂的控制逻辑。

5. 案例开发方向

  • 自定义按键映射(复杂组合键、宏命令)。
  • 模拟仪表或开关反馈(LED、震动反馈)。
  • 多设备联动(与脚蹬、推杆、仪表盘集成)。
  • 飞行模拟之外的用途(如工业设备控制、机械臂操控)。

5. 案例开发方向

  • 自定义按键映射(复杂组合键、宏命令)。
  • 模拟仪表或开关反馈(LED、震动反馈)。
  • 多设备联动(与脚蹬、推杆、仪表盘集成)。
  • 飞行模拟之外的用途(如工业设备控制、机械臂操控)。

我的需求是在window下进行C++开发,所以就需要DirectInput/XInput。  后面gpt就对这两种开发工具做了比较,简单来说就是对DirectInput和XInput开发工具进行比较。

您说:

DirectInput/XInput是什么软件?还是第三方库?

ChatGPT 说:

DirectInput和XInput都不是独立的软件或第三方库,而是微软提供的API(应用程序接口),用于在Windows系统上与输入设备(如游戏手柄、摇杆、方向盘)进行交互。

1. DirectInput

简介:DirectInput是微软DirectX的一部分,专门用于与各种输入设备(键盘、鼠标、摇杆、游戏手柄等)交互。

特点:

  • 支持多种设备,尤其是复杂的飞行摇杆和赛车方向盘。
  • 支持多按键、轴、旋钮、力反馈(Force Feedback)。
  • 不支持Xbox 360及更新设备(XInput替代)。
  • 适用场景:适合读取复杂的输入设备,如Thrustmaster HOTAS Warthog这种多轴、多按钮设备。
  • 开发语言支持:C/C++(DirectX SDK),C#(通过SharpDX或SlimDX封装)。

2. XInput

简介:XInput是微软专门为Xbox 360及更新型号的控制器设计的API。

特点:

  • 仅支持Xbox 360、Xbox One等标准手柄。
  • 不支持复杂的摇杆设备和力反馈功能(功能较简化)。
  • 简单易用,适合一般的游戏手柄开发。
  • 适用场景:主要用于开发支持Xbox手柄的PC游戏,不适合HOTAS Warthog这种设备。
  • 开发语言支持:C/C++,也有C#封装(如XInput.NET)。

      然后就是根据这个开发工具进行环境配置与软件部署

您说:

DirectInput怎么用于摇杆做第三方开发?

ChatGPT 说:

使用 DirectInput 与 Thrustmaster HOTAS Warthog 摇杆进行第三方开发,主要涉及设备初始化、输入读取和数据解析等步骤。:

1.开发工具:

  • 推荐使用 Visual Studio(Windows 环境)。
  • C++是DirectInput最常用的开发语言。

2.环境准备:

安装 DirectX SDK(适用于 DirectInput):

https://www.microsoft.com/zh-cn/download/details.aspx?id=8109

安装后,新建Visual Studio项目,并且配置头文件和库文件(这里路径很怪,在:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\x64目录下)。

链接库:

  • 右键项目 → 属性 → 链接器 → 输入 → 附加依赖项
  • 添加:dinput8.lib; dxguid.lib; d3d8.lib; winmm.lib
  • 注意: 我的该目录下只有 d3d9.lib;
  • 包含目录:
  • C/C++ → 常规 → 附加包含目录 → 添加 DirectX SDK 的 Include 目录。
  • 链接器 → 常规 → 附加库目录 → 添加 DirectX SDK 的 Lib 目录。

3. 注意VS的debug模式是x64

3硬件测试

安装了官网的驱动程序和测试软件,确定硬件方面还有连接是正常的


下载后驱动程序直接安装:

经过硬件测试软件确定硬件还有连接,动遥感(准心在动)还有按钮(亮灯)是没有问题的!:

4Debug

中间花了三个小时与GPT对战,互相debug,在一个阴暗的小角落里面通过手机+电脑飞快的查询问题。其中最严重的bug是获取设备的这个函数报错:

// 获取设备时打印详细错误码
hr = g_pJoystickDevice->Acquire();
if (FAILED(hr)) {std::cerr << "设备获取失败! 错误码: " << std::hex << hr << std::endl;return false;
}

一直提示没有管理员权限(返回0x80070005):


0x88780096 (DIERR_OTHERAPPHASPRIO):其他程序占用设备。
0x8878000C (DIERR_NOTACQUIRED):设备没有被获取。
0x8878000F (DIERR_INPUTLOST):输入设备丢失,需重新获取。
0x80070005 (E_ACCESSDENIED):权限不足(需要管理员权限)。

后面不知道Gpt给的啥代码,这个问题不提示了。最后的代码见下:
 

#include <windows.h>
#include <dinput.h>
#include <iostream>#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")LPDIRECTINPUT8 g_pDirectInput = nullptr;
LPDIRECTINPUTDEVICE8 g_pJoystickDevice = nullptr;bool InitDirectInput(HINSTANCE hInstance, HWND hWnd) {// 初始化 DirectInputif (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDirectInput, NULL))) {std::cerr << "DirectInput 初始化失败!" << std::endl;return false;}// 创建设备(默认获取第一个手柄)if (FAILED(g_pDirectInput->CreateDevice(GUID_Joystick, &g_pJoystickDevice, NULL))) {std::cerr << "无法创建摇杆设备!" << std::endl;return false;}// 设置数据格式if (FAILED(g_pJoystickDevice->SetDataFormat(&c_dfDIJoystick))) {std::cerr << "设置数据格式失败!" << std::endl;return false;}// 设置后台非独占模式if (FAILED(g_pJoystickDevice->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))) {std::cerr << "设置协作级别失败!" << std::endl;return false;}// 获取设备控制权if (FAILED(g_pJoystickDevice->Acquire())) {std::cerr << "设备获取失败!" << std::endl;return false;}std::cout << "DirectInput 初始化成功,正在监听摇杆输入..." << std::endl;return true;
}void ReadJoystickState() {DIJOYSTATE js;HRESULT hr = g_pJoystickDevice->Poll();  // 轮询设备状态if (FAILED(hr)) {// 设备可能丢失,尝试重新获取g_pJoystickDevice->Acquire();return;}// 获取设备状态if (FAILED(g_pJoystickDevice->GetDeviceState(sizeof(DIJOYSTATE), &js))) {std::cerr << "读取设备状态失败!" << std::endl;return;}// 打印摇杆信息std::cout << "X轴: " << js.lX << "  Y轴: " << js.lY << "  Z轴: " << js.lZ << std::endl;
}void CleanUp() {if (g_pJoystickDevice) {g_pJoystickDevice->Unacquire();g_pJoystickDevice->Release();g_pJoystickDevice = nullptr;}if (g_pDirectInput) {g_pDirectInput->Release();g_pDirectInput = nullptr;}
}int main() {HINSTANCE hInstance = GetModuleHandle(NULL);HWND hWnd = GetConsoleWindow();  // 使用控制台窗口句柄if (!InitDirectInput(hInstance, hWnd)) {std::cerr << "DirectInput 初始化失败,程序终止!" << std::endl;return -1;}// 持续读取摇杆数据while (true) {ReadJoystickState();Sleep(2000);  // 每100ms读取一次}CleanUp();return 0;
}

最后效果展示如下

6后续

可惜只要求我写个demo,具体还没要求我干啥,能读遥感数据就行,按钮后面有需求再写demo吧。

完结,撒花


http://www.ppmy.cn/news/1563679.html

相关文章

【C语言】线程----同步、互斥、条件变量

目录 3. 同步 3.1 概念 3.2 同步机制 3.3 函数接口 1. 同步 1.1 概念 同步(synchronization)指的是多个任务(线程)按照约定的顺序相互配合完成一件事情 1.2 同步机制 通过信号量实现线程间的同步 信号量&#xff1a;通过信号量实现同步操作&#xff1b;由信号量来决定…

数据结构《MapSet哈希表》

文章目录 一、搜索树1.1 定义1.2 模拟实现搜索 二、Map2.1 定义2.2 Map.Entry2.3 TreeMap的使用2.4 Map的常用方法 三、Set3.1 定义3.2 TreeSet的使用3.3 Set的常用方法 四、哈希表4.1 哈希表的概念4.2 冲突4.2.1 冲突的概念4.2.2 冲突的避免1. 选择合适的哈希函数2. 负载因子调…

【寒假逆袭计划】自学黑客计划(网络安全)

CSDN大礼包&#xff1a;&#x1f449;基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 前言 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&…

记录一个v-if与自定义指令的BUG

在做某个系统的时候因为element自带的v-input和v-input-number不能满足所需要的功能&#xff0c;例如限制小数位数&#xff0c;最大值最小值和值是否允许存在非0之类的状态&#xff0c;写了一个自定义指令v-onlyNumber来满足需求(v-onlyNumber在我其他文章内有直接copy就行)&am…

Ubuntu 磁盘修复

Ubuntu 磁盘修复 在 ubuntu 文件系统变成只读模式&#xff0c;该处理呢&#xff1f; 文件系统内部的错误&#xff0c;如索引错误、元数据损坏等&#xff0c;也可能导致系统进入只读状态。磁盘坏道或硬件故障也可能引发文件系统只读的问题。/etc/fstab配置错误&#xff0c;可能…

全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之一维数组(应用一)

实战训练1—小明摘桃子 问题描述&#xff1a; 小明家院子里有棵桃树&#xff0c;桃子成熟的时候&#xff0c;小明就会带着30厘米高的板凳跑去摘桃子&#xff0c;当他不能直接用手摘到桃子的时候&#xff0c;就会踩到板凳上再试试。桃树上每次都是10个桃子&#xff0c;现在已知…

RabbitMQ(四)

SpringBoot整合RabbitMQ SpringBoot整合1、生产者工程①创建module②配置POM③YAML④主启动类⑤测试程序 2、消费者工程①创建module②配置POM③YAML文件内配置&#xff1a; ④主启动类⑤监听器 3、RabbitListener注解属性对比①bindings属性②queues属性 SpringBoot整合 1、生…

【Vim Masterclass 笔记12】S06L26 + L27:Vim 文本的搜索、查找及替换同步练习(含点评课)

文章目录 S06L26 Exercise 07 - Search, Find, and Replace1 训练目标2 操作指令2.1. 打开 search-practice.txt 文件2.2. 同一行内的搜索练习2.3. 当前文件内的搜索练习2.4. 单词搜索练习2.5. 全局替换练习 3 退出 Vim S06L27 同步练习点评课 写在前面 Vim 的文本检索、查找与…