当前位置: 首页 > article >正文

Thrustmaster Hotas Warthog飞行操作杆开发

目录

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) {
    // 初始化 DirectInput
    if (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.kler.cn/a/507508.html

相关文章:

  • 【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)
  • 前端【2】html添加样式、CSS选择器
  • redhat安装docker 24.0.7
  • Spring Boot 下的Swagger 3.0 与 Swagger 2.0 的详细对比
  • SpringMVC——原理简介
  • 代理模式实现
  • [cg] glDrawBuffers MRT的应用
  • 【0x3D】HCI_Remote_Host_Supported_Features_Notification事件详解
  • 1.7 ChatGPT:引领AI对话革命的致胜之道
  • 冯康简介,中国有限元先驱
  • 基于HPM6750实现一个UVC和MSC的符合类设备
  • Flink CDC解决数据库同步,异常情况下增量、全量问题
  • Vue前端框架概述
  • 数据持久层:构建应用程序与数据源的桥梁
  • Ncat: bind to :::7777: Address already in use报错问题解决
  • 牛客小白月赛109 A-C
  • vue2:实现上下两栏布局,可拖拽改变高度
  • 楚慧杯Web
  • 【Linux】常用指令详解二
  • 【Spring Cloud Alibaba】基于Spring Boot 3.x 搭建教程
  • CVPR 2024 机器学习方向总汇(多任务、联邦学习、迁移学习和对抗等)
  • PHP转向Python时需要注意的地方
  • 米塔 v0.921 PC/手机版双端 全MOD+全服装(MiSide)免安装中文版 游戏推荐 免费下载
  • RV1126+FFMPEG推流项目(3)VI模块视频编码流程
  • 在PyCharm中使用Anaconda中的虚拟环境
  • Apache PAIMON 学习