Thrustmaster Hotas Warthog飞行操作杆开发

ops/2025/1/18 10:56:00/

目录

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/ops/150782.html

相关文章

指针的进阶

指针的主题&#xff0c;我们在初级阶段的《指针》章节已经接触过了&#xff0c;我们知道了指针的概念&#xff1a; 1. 指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间。 2. 指针的大小是固定的4/8个字节&#xff08;32位平台/64位平台&#xff0…

万字图文:SaaS业务架构、价值流、业务能力、业务流程、业务对象、组织架构

大家好&#xff0c;我是汤师爷~ 本文为读者提供一个SaaS业务架构的系统性框架&#xff0c;探讨业务架构分析的核心要素&#xff0c;帮助SaaS企业深入剖析目标客户的业务模式&#xff0c;全面理解他们的业务架构。 无论你是SaaS创业者、产品经理还是架构师&#xff0c;本文内容…

JS后盾人--JS数组挖掘(少年篇)

数组引用类型分析 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </he…

AndroidStudio升级到2024.2.2项目AGP升级8.8.0版本记录

背景 升级as&#xff0c;一般会把agp一起升级。我的原来版本是8.7.2 plugins {id com.android.application version 8.7.2 apply falseid com.android.library version 8.7.2 apply falseid org.jetbrains.kotlin.android version 1.8.10 apply false }升级后版本&#xff1a…

JVM之内存泄漏的详细解析

内存泄漏 泄露溢出 内存泄漏&#xff08;Memory Leak&#xff09;&#xff1a;是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放&#xff0c;造成系统内存的浪费&#xff0c;导致程序运行速度减慢甚至系统崩溃等严重后果 可达性分析算法来判断对象是否是不再使…

HTML5 加载动画(Loading Animation)

加载动画&#xff08;Loading Animation&#xff09;详解 概述 加载动画是指在数据加载过程中&#xff0c;向用户展示的一种视觉效果&#xff0c;旨在提升用户体验&#xff0c;告知用户系统正在处理请求。它可以减少用户的等待焦虑感&#xff0c;提高界面的互动性。 常见的加…

(三)html2canvas将HTML 转为图片并实现下载

将 HTML 转为图片并实现下载&#xff0c;通常可以使用一个叫做 html2canvas 的 JavaScript 库。html2canvas 能够将 HTML 元素及其样式渲染成一个画布 (Canvas)&#xff0c;然后将该画布转换为图片格式&#xff08;如 PNG 或 JPEG&#xff09;&#xff0c;最终提供下载功能。 …

类模板的使用方法

目录 类模板的使用方法 1.类模板语法 2.类模板和函数模板区别 3.类模板中成员函数创建时机 4.类函数对象做函数参数 5.类模板和继承 6.类模板成员函数类外实现 7.类模板分文件编写 person.hpp 实现cpp文件&#xff1a; 8.类模板与友元 9.类模板案例 MyArray.hpp …