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吧。

完结,撒花

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/953728.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法-查找数组对角线上最大的质数

力扣题目&#xff1a;2614. 对角线上的质数 - 力扣&#xff08;LeetCode&#xff09; 给你一个下标从 0 开始的二维整数数组 nums 。 返回位于 nums 至少一条 对角线 上的最大 质数 。如果任一对角线上均不存在质数&#xff0c;返回 0 。 注意&#xff1a; 如果某个整数大于…

电梯系统的UML文档02

现在我们来回答用UML 设计电梯系统的实践中遇到的问题&#xff1a;“UML 是一种适合于实时系统的建模语言吗?”我们发现基于上段提到的特征&#xff0c;UML 是适合的但有不足。用UML 设计实时系统有以下问题&#xff1a; •特定硬件及它们特征的定义。 •在对象、任务和硬件层…

mysql set age=‘0‘ 和 set age=0的区别?

select case when(t1.business_transfer‘source’)then 0 else t1.settlement_tyy_cash_amount end as tyy from t_settlement_waybill t1 where waybill_sn in (‘2025010700001’); select case when(t1.business_transfer‘source’)then (t1.settlement_tyy_cash_amount‘…

利用Java爬虫按图搜索1688商品(拍立淘)的实践指南

在当今数字化时代&#xff0c;网购已成为人们生活中不可或缺的一部分。而1688作为国内领先的B2B电商平台&#xff0c;汇聚了海量的商品资源。然而&#xff0c;在面对众多商品时&#xff0c;传统的文字搜索方式有时难以满足我们的需求。比如&#xff0c;当我们看到一件心仪的商品…

达梦8-DMSQL程序设计学习笔记1-DMSQL程序简介

1、DMSQL程序简介 DMSQL程序是达梦数据库对标准SQL语言的扩展&#xff0c;是一种过程化SQL语言。在DMSQL程序中&#xff0c;包括一整套数据类型、条件结构、循环结构和异常处理结构等&#xff0c;DMSQL程序中可以执行SQL语句&#xff0c;SQL语句中也可以使用DMSQL函数。 DMSQ…

使用 WPF 和 C# 将纹理应用于三角形

此示例展示了如何将纹理应用于三角形,以使场景比覆盖纯色的场景更逼真。以下是为三角形添加纹理的基本步骤。 创建一个MeshGeometry3D对象。像往常一样定义三角形的点和法线。通过向网格的TextureCoordinates集合添加值来设置三角形的纹理坐标。创建一个使用想要显示的纹理的 …

Git版本控制 - 创建使用Repository

Git版本控制 – 创建使用Repository Version Control with Git - Create and Use Repository By JacksonML 上文提到&#xff0c;Git是一种分布式版本控制系统。作为全球范围内广泛使用的工具&#xff0c;如何将项目分步骤运用到其中呢&#xff1f; 本文简要介绍如何用Git工…

WINFORM - DevExpress -> devexpress版--报表(report)

devexpress report模板 1.安装devexpress(DevExpress 总结【安装、案例】_caoyanchao1的博客-CSDN博客_devexpress) 2.新建vs项目且添加standarReportDesigner控件 涛神设计器注意 3.运行后步骤 点击New Report DetailReport 涛神设计器checkbox(3.复选框只认boolean类型的 b…

【Redis】初识Redis

目录 Redis简介 Redis在内存中存储数据 Redis数据库中的应用 Redis缓存中的应用 Redis消息中间件 尾言 Redis简介 如下是Redis官网中&#xff0c;对Redis的一段描述 在这段描述中&#xff0c;我们提取如下关键要点&#xff1a; Redis主要用于在内存中存储数据Redis可…

YOLOv9改进,YOLOv9自研检测头融合HAttention用于图像修复的混合注意力检测头

参考文章 完成本篇内容,首先完成这篇文章,并把代码添加到 YOLOv9 中: YOLOv9改进,YOLOv9引入HAttention注意机制用于图像修复的混合注意力转换器,CVPR2023,超分辨率重建 下文都是手把手教程,跟着操作即可添加成功 目录 参考文章🎓一、YOLOv9原始版本代码下载🍀🍀…

[读书日志]8051软核处理器设计实战(基于FPGA)第七篇:8051软核处理器的测试(verilog+C)

6. 8051软核处理器的验证和使用 为了充分测试8051的性能&#xff0c;我们需要测试每一条指令。在HELLO文件夹中存放了整个测试的C语言工程文件。主函数存放在指令被分为五大类&#xff0c;和上面一样。 打开后是这样的文件结构。HELLO.c是主文件&#xff0c;这是里面的代码&am…

occ的开发框架

occ的开发框架 1.Introduction This manual explains how to use the Open CASCADE Application Framework (OCAF). It provides basic documentation on using OCAF. 2.Purpose of OCAF OCAF (the Open CASCADE Application Framework) is an easy-to-use platform for ra…

python识别图片中指定颜色的图案并保存为图片

示例代码&#xff1a; def chuli(color):import cv2import numpy as np# 定义颜色名称到HSV阈值范围的映射color_thresholds {red: ([0, 100, 100], [10, 255, 255], [160, 100, 100], [180, 255, 255]),yellow: ([20, 100, 100], [30, 255, 255]),blue: ([90, 100, 100], [1…

《利用深度神经网络在广角小口径望远镜中实现天文目标的检测与分类》论文精读

摘要 大口径小口径望远镜被广泛应用于光学瞬态观测&#xff0c;对观测图像中的天文目标进行检测和分类是最重要也是最基础的步骤。本文提出了一种基于深度神经网络的天文目标检测与分类框架。该框架采用了Faster R-CNN的概念&#xff0c;以改进的Resnet-50为主干网络&#xff…

Redis数据结构服务器

Redis数据结构服务器 什么是Redis数据结构服务器 的概念和特点 是一个开源&#xff08;BSD许可&#xff09;&#xff0c;内存中的数据结构存储服务器&#xff0c;可用作数据库、缓存和消息中间件。它支持多种类型的数据结构&#xff0c;如字符串&#xff08;strings&#xff09…

逻辑测试题

https://blog.csdn.net/qq_39081315/article/details/121393597 先生成一个点&#xff0c;每生成一个点判断距离&#xff0c;角度&#xff0c;满足加入存点的容器&#xff0c;直到容器大小为4。 随机生成点&#xff1a; 分区域&#xff1a;最大距离20&#xff0c;以20为正方形…

【UE5 C++课程系列笔记】27——多线程基础——ControlFlow插件的基本使用

目录 步骤 一、搭建基本同步框架 二、添加委托 三、添加蓝图互动框架 四、修改为异步框架 完整代码 通过一个游戏初始化流程的示例来介绍“ControlFlows”的基本使用。 步骤 一、搭建基本同步框架 1. 勾选“ControlFlows”插件 2. 新建一个空白C类&#xff0c;这里…

前端性能优化方面

页面加载过程 网页资源的加载通常需要以下基本步骤&#xff1a; 地址栏输入网页服务器地址 浏览器获取网页html文件 解析html文件中存在的js、css、图片等资源&#xff0c;通过网络线程加载 在特定时机执行js代码&#xff0c;可以在js中动态加载需要的静态资源 执行js里存在的f…

解锁“搭子小程序”开发新机遇,助力企业数字化转型

搭子作为一种新型的社交方式&#xff0c;逐渐进入到了年轻人的生活中&#xff0c;在日常旅游、学习、逛街等&#xff0c;年轻人都可以找到志同道合的“搭子”&#xff0c;提高生活的幸福指数。 随着搭子市场的发展&#xff0c;通过互联网寻找搭子已经成为了年轻人的必备方式。…

Open FPV VTX开源之ardupilot配置

Open FPV VTX开源之ardupilot配置 1. 源由2. 配置3. 总结4. 参考资料5. 补充5.1 飞控固件版本5.2 配置Ardupilot的BF OSD5.3 OSD偏左问题 1. 源由 飞控嵌入式OSD - ardupilot配置使用ardupliot配套OSD图片。 Choose correct font depending on Flight Controller SW. ──>…