IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 罗技F310与F710游戏手柄驱动(附C++源码) -> 正文阅读

[C++知识库]罗技F310与F710游戏手柄驱动(附C++源码)

一. 简介



Logitech F310游戏手柄是Logitech公司生产的双模拟摇杆,动式方向按键游戏手柄。

游戏手柄的作用不只是可以用来玩游戏,还可以用于做一些机器人仿真,就比如最近MIT开源的Mini Cheetah四足机器人,其中机器人仿真部分用的控制器就是罗技F310游戏手柄。但是其采用的方法是直接调用QT中的QtGamepad库操作手柄,对于没有安装QT的人没办法直接调用,为此我写了一份罗技F310的通用驱动,驱动也兼容F710,其他型号的游戏手柄还未测试。

代码目前只支持Linux,可以实现读取所有遥感和按键的数值,最终效果如下:

驱动手柄并将各个按键值打印出来:


使用QT将功能做UI显示:

二. 源码

1. 头文件

Logitech_controller.h :

/*========================= Logitech_controller ==========================*/
 /* @file    Logitech_controller.h
  * @author  lindongdong
  * @brief   详情请看Logitech_controller.cpp
*/ 												 
/*========================= Logitech_controller ==========================*/

/* define ----------------------------------------------------------------*/
#ifndef Logitech_DRIVER
#define Logitech_DRIVER

/* Includes ---------------------------------------------------------------*/
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <string.h>
#include <stdio.h>
#include <map>

#define JSKEY_A     0x001
#define JSKEY_B     0x101
#define JSKEY_X     0x201
#define JSKEY_Y     0x301

#define JSKEY_LB    0x401
#define JSKEY_RB    0x501
#define JSKEY_BACK  0x601
#define JSKEY_START 0x701
#define JSKEY_HOME  0x801

#define JSKEY_LT 0x202
#define JSKEY_RT 0x502

#define JSKEY_CROSS_X 0x602
#define JSKEY_CROSS_Y 0x702
#define JSKEY_LEFTSTICK_X 0x002
#define JSKEY_LEFTSTICK_Y 0x102
#define JSKEY_RIGHTSTICK_X 0x302
#define JSKEY_RIGHTSTICK_Y 0x402

#define JSKEY_PRESS 0x001    
#define JSKEY_RELEASE 0x0    

#define JSKEY_CROSS_LOW_VALUE 0xffff8001 
#define JSKEY_CROSS_HIGH_VALUE 0x7fff   

using namespace std;

class Logitech{
private:
    char *dev;
    ssize_t n;
    int fd;
    int buf[2];
public:
    Logitech(char* device);
    map<int, int> Keystate_map;
    int  init();
    void listen_input();
    void print_key_state();
};
#endif //Logitech_DRIVER

2. 源文件

Logitech_controller.c :

/*========================= Gamepad Control ================================*/
 /* Copyright (C) 2021 - ~, SCUT-RobotLab Development Team
  * @file    Logitech_controller.cpp
  * @author  lindongdong
  * @brief   罗技遥控器的驱动库,库目前支持罗技遥控器型号:F710、F310。
  * @note 
  *         - 注意按键值所对应的意义。
  *         - 当手柄 Mode为黄灯时,左边上下左右按键与左边遥感值互换,按键按下为对应遥感边界值(+-1)
  *           遥感推至极限为对应按键值。
  *         - 一般情况下使用非黄灯模式。
  * @method 
  *         - 1. 手柄驱动路径     : char path[] = "/dev/input/js0";
  *         - 2. 定义一个遥控器类  : Logitech Logitech(path);
  *         - 3. 遥控器类初始化    : Logitech.init();
  *         - 4. 线程中进行数据接受 : Logitech.listen_input();
  * @warning 
  *         - At least C++11 is required.	
  *         - Only linux platform is supported for now.
*/ 												 
/*========================= Gamepad Control ================================*/

/* Includes ----------------------------------------------------------------*/
#include "Logitech_controller.h"

using namespace std;

Logitech::Logitech(char* device)
{
    dev = device;
    memset(buf, 0, sizeof buf);
}

int Logitech::init()
{
    fd = open(dev, O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "Cannot open %s: %s.\n", dev, strerror(errno));
        return EXIT_FAILURE;
    }
    /*Key Status*/

    /* 0 is released */
    /* 1 is press    */
    Keystate_map[JSKEY_A] =0;
    Keystate_map[JSKEY_B] =0;
    Keystate_map[JSKEY_X] =0;
    Keystate_map[JSKEY_Y] =0;

    /* 0 is released */
    /* 1 is press    */
    Keystate_map[JSKEY_LB] =0;
    Keystate_map[JSKEY_RB] =0;
   
    /* 0 is released */
    /* 1 is press    */
    Keystate_map[JSKEY_BACK] =0;
    Keystate_map[JSKEY_START] =0;
    Keystate_map[JSKEY_HOME] =0;
    
    /*  0 is released */
    /* -1 is the left or up button is pressed */
    /*  1 is the right or down button is pressed*/
    Keystate_map[JSKEY_CROSS_X] =0;
    Keystate_map[JSKEY_CROSS_Y] =0;

    /* the result is the value of the key(0~99)*/
    Keystate_map[JSKEY_LT] =0;
    Keystate_map[JSKEY_RT] =0;

    /* the result is the value of the key(-100~100)*/
    Keystate_map[JSKEY_LEFTSTICK_X] =0;
    Keystate_map[JSKEY_LEFTSTICK_Y] =0;
    Keystate_map[JSKEY_RIGHTSTICK_X] =0;
    Keystate_map[JSKEY_RIGHTSTICK_Y] =0;

    return 0;
}

void Logitech::listen_input()
{
    while (1) {
        memset(buf, 0, sizeof buf);
        n = read(fd, &buf, sizeof buf);
        n = n / sizeof(int);
        if (n == (ssize_t)-1) {
            if (errno == EINTR)
                continue;
            else
                break;
        }

        unsigned short btn = buf[1] >> 16;
        short val = (short)(buf[1] & 0xffff);

         /*Test for button ID*/
         //cout<<"0x"<<hex<<btn<<endl;

        if (btn == JSKEY_LT || btn == JSKEY_RT)
        {
            unsigned short prs_val = val + 32768;
            val = (unsigned short) (((long)prs_val)*100/65536);
            Keystate_map[btn]= val;
        }
        else if (btn == JSKEY_LEFTSTICK_X || btn == JSKEY_LEFTSTICK_Y ||
                 btn == JSKEY_RIGHTSTICK_X || btn == JSKEY_RIGHTSTICK_Y)
        {
            /* y-axis reverse */
            if(btn==JSKEY_LEFTSTICK_Y||btn == JSKEY_RIGHTSTICK_Y)
            {val=(-1)*val;}
            val = val*100/32767;
            Keystate_map[btn]= val;
        }
        else
        {
            switch (val)
            {
            case JSKEY_PRESS:
                Keystate_map[btn]=1;
                break;
            case JSKEY_RELEASE:
                Keystate_map[btn]=0;
                break;
            case JSKEY_CROSS_LOW_VALUE:
                Keystate_map[btn]=-1;
                break;
            case JSKEY_CROSS_HIGH_VALUE:
                Keystate_map[btn]=1;
                break;
            default:
                break;
            }
            /* y-axis reverse */
            if(btn==JSKEY_CROSS_Y)
            {Keystate_map[btn]=(-1)*Keystate_map[btn];}
        }
        print_key_state();
    }
}

void Logitech::print_key_state()
{
   cout<<endl;
   cout<<"JSKEY_A = "<<Keystate_map[JSKEY_A]<<endl;
   cout<<"JSKEY_B = "<<Keystate_map[JSKEY_B]<<endl;
   cout<<"JSKEY_X = "<<Keystate_map[JSKEY_X]<<endl;
   cout<<"JSKEY_Y = "<<Keystate_map[JSKEY_Y]<<endl;

   cout<<"JSKEY_LB = "<<Keystate_map[JSKEY_LB]<<endl;
   cout<<"JSKEY_RB = "<<Keystate_map[JSKEY_RB]<<endl;
   cout<<"JSKEY_BACK = "<<Keystate_map[JSKEY_BACK]<<endl;
   cout<<"JSKEY_START = "<<Keystate_map[JSKEY_START]<<endl;
   cout<<"JSKEY_HOME = "<<Keystate_map[JSKEY_HOME]<<endl;

   cout<<"JSKEY_LT = "<<Keystate_map[JSKEY_LT]<<endl;
   cout<<"JSKEY_RT = "<<Keystate_map[JSKEY_RT]<<endl;

   cout<<"JSKEY_CROSS_X = "<<Keystate_map[JSKEY_CROSS_X]<<endl;
   cout<<"JSKEY_CROSS_Y = "<<Keystate_map[JSKEY_CROSS_Y]<<endl;

   cout<<"JSKEY_LEFTSTICK_X  = "<<Keystate_map[JSKEY_LEFTSTICK_X] <<"     JSKEY_LEFTSTICK_Y   = "<<Keystate_map[JSKEY_LEFTSTICK_Y]<<endl;
   cout<<"JSKEY_RIGHTSTICK_X = "<<Keystate_map[JSKEY_RIGHTSTICK_X]<<"     JSKEY_RIGHTSTICK_Y = "<<Keystate_map[JSKEY_RIGHTSTICK_Y]<<endl;
}


3. 测试代码

Logitech_controller_test.cpp :

#include "Logitech_controller.h"

using namespace std;

int main()
{
    char path[] = "/dev/input/js0";
    Logitech gamepad(path);

    gamepad.init();
    gamepad.listen_input();

    return 0;
}

三. 源码下载链接

以上例程中的代码如下:

  1. 罗技遥控手柄驱动测试代码下载链接
  2. 基于QT的罗技遥控手柄驱动测试下载链接

开发环境:

  • ubuntu18.04
  • Qt5.10.0
  • Cmake 3.10.2
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-08 11:36:46  更:2021-10-08 11:38:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:20:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码