Ubuntu joystick 测试手柄 xbox

news2024/12/25 23:36:40

Ubuntu joystick 测试手柄 xbox

测试使用Ubuntu20.04 测试环境在工控机

安装测试

实际测试使用的手柄是北通阿修罗2pro
兼容xbox

Ubuntu20.04主机

连接手柄或者无线接收器后查看是否已经检测到:

ls /dev/input

找到输入中的 js0 即为手柄输入
在这里插入图片描述

需要安装joystick安装包:

sudo apt install joystick

测试手柄的数据输入:

jstest /dev/input/js0

在这里插入图片描述

测试代码

->>>完整的项目代码:

https://gitee.com/tianxiaohuahua/joystick_code

driver_Xbox_Joystick.cpp

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/joystick.h>

#include "driver_Xbox_Joystick.h"

 
 /* 获得手柄设备输入流 */
int xbox_open(char *file_name)
{
    int xbox_fd;
 
    xbox_fd = open(file_name, O_RDONLY);
    if (xbox_fd < 0)
    {
        perror("open");
        return -1;
    }
 
    return xbox_fd;
}
 
 /* 读取手柄数据 */
int xbox_map_read(int xbox_fd, xbox_map_t *map)
{
    int len, type, number, value;
    struct js_event js;
 
    len = read(xbox_fd, &js, sizeof(struct js_event));
    if (len < 0)
    {
        perror("read");
        return -1;
    }
 
    type = js.type;
    number = js.number;
    value = js.value;
 
    map->time = js.time;
 
    if (type == JS_EVENT_BUTTON)
    {
        switch (number)
        {
            case XBOX_BUTTON_A:
                map->a = value;
                break;
 
            case XBOX_BUTTON_B:
                map->b = value;
                break;
 
            case XBOX_BUTTON_X:
                map->x = value;
                break;
 
            case XBOX_BUTTON_Y:
                map->y = value;
                break;
 
            case XBOX_BUTTON_LB:
                map->lb = value;
                break;
 
            case XBOX_BUTTON_RB:
                map->rb = value;
                break;
 
            case XBOX_BUTTON_SELECT:
                map->select = value;
                break;
 
            case XBOX_BUTTON_START:
                map->start = value;
                break;
 
            case XBOX_BUTTON_HOME:
                map->home = value;
                break;
 
            case XBOX_BUTTON_LO:
                map->lo = value;
                break;
 
            case XBOX_BUTTON_RO:
                map->ro = value;
                break;
 
            default:
                break;
        }
    }
    else if (type == JS_EVENT_AXIS)
    {
        switch(number)
        {
            case XBOX_AXIS_LX:
                map->lx = value;
                break;
 
            case XBOX_AXIS_LY:
                map->ly = value;
                break;
 
            case XBOX_AXIS_RX:
                map->rx = value;
                break;
 
            case XBOX_AXIS_RY:
                map->ry = value;
                break;
 
            case XBOX_AXIS_LT:
                map->lt = value;
                break;
 
            case XBOX_AXIS_RT:
                map->rt = value;
                break;
 
            case XBOX_AXIS_XX:
                map->xx = value;
                break;
 
            case XBOX_AXIS_YY:
                map->yy = value;
                break;
 
            default:
                break;
        }
    }
    else
    {
        /* 若出错 */
    }
 
    return len;
}

/* 关闭手柄设备输入流 */ 
void xbox_close(int xbox_fd)
{
    close(xbox_fd);
    return;
}
 
 
 
int test(void)
{
    int xbox_fd ;
    xbox_map_t map;
    int len, type;
    int axis_value, button_value;
    int number_of_axis, number_of_buttons ;
 
    memset(&map, 0, sizeof(xbox_map_t));
 
    xbox_fd = xbox_open((char*)("/dev/input/js0"));
    if(xbox_fd < 0)
    {
        return -1;
    }
 
    while(1)
    {
        len = xbox_map_read(xbox_fd, &map);
        if (len < 0)
        {
            usleep(10*1000);
            continue;
        }
 
        printf("\rTime:%8d A:%d B:%d X:%d Y:%d LB:%d RB:%d select:%d start:%d lo:%d ro:%d XX:%-6d YY:%-6d LX:%-6d LY:%-6d RX:%-6d RY:%-6d LT:%-6d RT:%-6d",
                map.time, map.a, map.b, map.x, map.y, map.lb, map.rb, map.select, map.start, map.lo, map.ro,
                map.xx, map.yy, map.lx, map.ly, map.rx, map.ry, map.lt, map.rt);
        fflush(stdout);
    }
 
    xbox_close(xbox_fd);
    return 0;
}

JoyStickDriver::JoyStickDriver(){
    JoyStickInit();
}

JoyStickDriver::~JoyStickDriver(){
    JoyStickClose();
}

int JoyStickDriver::JoyStickInit(){
    JoystickFd = xbox_open((char*)("/dev/input/js0"));
    if(JoystickFd < 0) {
        return -1;
    }
    return 0;
}

int JoyStickDriver::JoyStickRead(xbox_map_t *pMap){
    return xbox_map_read(JoystickFd, pMap);
}

int JoyStickDriver::JoyStickRead(void){
    return xbox_map_read(JoystickFd, &joystickData);
}

int JoyStickDriver::JoyStickClose(){
    xbox_close(JoystickFd);
    return 0;
}

driver_Xbox_Joystick.h

#ifndef driver_Xbox_Joystick_H
#define driver_Xbox_Joystick_h

/* 手柄面板上所有可控制按键/轴(包括一个时间量) */ 
typedef struct xbox_map
{
    int     time;
    int     a;
    int     b;
    int     x;
    int     y;
    int     lb;
    int     rb;
    int     select;
    int     start;
    int     home;
    int     lo;
    int     ro;
 
    int     lx;
    int     ly;
    int     rx;
    int     ry;
    int     lt;
    int     rt;
    int     xx;
    int     yy;
}xbox_map_t;

#define XBOX_TYPE_BUTTON    0x01
#define XBOX_TYPE_AXIS      0x02
 
#define XBOX_BUTTON_A       0x00
#define XBOX_BUTTON_B       0x01
#define XBOX_BUTTON_X       0x02
#define XBOX_BUTTON_Y       0x03
#define XBOX_BUTTON_LB      0x04
#define XBOX_BUTTON_RB      0x05
#define XBOX_BUTTON_SELECT  0x06
#define XBOX_BUTTON_START   0x07
#define XBOX_BUTTON_HOME    0x08
#define XBOX_BUTTON_LO      0x09    /* 左摇杆按键 */
#define XBOX_BUTTON_RO      0x0a    /* 右摇杆按键 */
 
#define XBOX_BUTTON_ON      0x01
#define XBOX_BUTTON_OFF     0x00
 
#define XBOX_AXIS_LX        0x00    /* 左摇杆X轴 */
#define XBOX_AXIS_LY        0x01    /* 左摇杆Y轴 */
#define XBOX_AXIS_RX        0x03    /* 右摇杆X轴 */
#define XBOX_AXIS_RY        0x04    /* 右摇杆Y轴 */
#define XBOX_AXIS_LT        0x02
#define XBOX_AXIS_RT        0x05
#define XBOX_AXIS_XX        0x06    /* 方向键X轴 */
#define XBOX_AXIS_YY        0x07    /* 方向键Y轴 */
 
#define XBOX_AXIS_VAL_UP        -32767
#define XBOX_AXIS_VAL_DOWN      32767
#define XBOX_AXIS_VAL_LEFT      -32767
#define XBOX_AXIS_VAL_RIGHT     32767
 
#define XBOX_AXIS_VAL_MIN       -32767
#define XBOX_AXIS_VAL_MAX       32767
#define XBOX_AXIS_VAL_MID       0x00
 
 
int test(void);

class JoyStickDriver {
public:
    xbox_map_t joystickData;
    JoyStickDriver(void);
    ~JoyStickDriver(void);
    int JoyStickInit(void);
    int JoyStickRead(xbox_map_t *pMap);
    int JoyStickRead(void);
    int JoyStickClose();

private:
    int JoystickFd ;

};

#endif

main.cpp

#include <iostream>
#include "main.h"

int main(int argc, char *argv[])
{
    std::cout << "123" << std::endl;
    JoyStickDriver  joystick;
    

    while(1)
    {
        int len = joystick.JoyStickRead();
        if (len < 0)
        {
            usleep(10*1000);
            continue;
        }
 
        printf("\rTime:%8d A:%d B:%d X:%d Y:%d LB:%d RB:%d select:%d start:%d lo:%d ro:%d XX:%-6d YY:%-6d LX:%-6d LY:%-6d RX:%-6d RY:%-6d LT:%-6d RT:%-6d",
                joystick.joystickData.time, 
                joystick.joystickData.a, joystick.joystickData.b, 
                joystick.joystickData.x, joystick.joystickData.y, 
                joystick.joystickData.lb, joystick.joystickData.rb, 
                joystick.joystickData.select, joystick.joystickData.start, 
                joystick.joystickData.lo, joystick.joystickData.ro,
                joystick.joystickData.xx, joystick.joystickData.yy, 
                joystick.joystickData.lx, joystick.joystickData.ly, 
                joystick.joystickData.rx, joystick.joystickData.ry, 
                joystick.joystickData.lt, joystick.joystickData.rt);
        fflush(stdout);
    }
    return 0;
}

CMakeList.txt

# VERSION需要和本机安装的Cmake对应
cmake_minimum_required(VERSION 3.10.2) 

# 指定了当前的工程名称,最后输出的可执行文件名称,赋值给了{PROJECT_NAME}变量
project(app) 

# c++ 11
set(CMAKE_CXX_FLAGS "-std=c++11")

# 添加头文件
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/include/driver)

# 查找指定目录下的所有.cpp与.h文件 并存放到指定变量名{SC_FILES}FILE(GLOB 
    SC_FILES 
    ${PROJECT_SOURCE_DIR}/src/driver/driver_Xbox_Joystick.cpp 
    )

#####生成可执行文件
# 使用指定的源文件创建出一个可执行文件,第一个变量必须是可执行文件的名字,后面默认是其他源文件
add_executable(${PROJECT_NAME} ${SC_FILES} ${PROJECT_SOURCE_DIR}/src/main.cpp) 
# 指定链接给定目标和/或其依赖项时要使用的库或标志,链接动态库静态库等

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

new mars3d.layer.XyzLayer({的rectangle瓦片数据的矩形区域范围说明

new mars3d.layer.XyzLayer({的rectangle瓦片数据的矩形区域范围说明 2.这个xyz图层的矩形区域范围rectangle从图层文件中无法获取&#xff0c;但是看图层文件可以知道这个是12-21级的数据。 3.一般这个图层数据文件服务会有提供相应的rectangle范围&#xff0c;在服务的xml文…

Centos 7 安装通过yum安装google浏览器

在CentOS 7上使用yum安装Google Chrome浏览器稍微复杂一些&#xff0c;因为Chrome并不直接包含在默认的Yum仓库中。按照以下步骤来操作&#xff1a; 1、添加Google Chrome仓库 首先&#xff0c;您需要手动添加Google Chrome的Yum仓库。打开终端&#xff0c;并使用文本编辑器&a…

NAT地址转换内外网通信

实验要求&#xff1a;内网地址通过nat转换成外网地址&#xff0c;联通外网服务器&#xff0c;达到内网外网互通 拓扑结构&#xff1a; 配置完成后&#xff0c;在ar1的G1口设置抓包&#xff0c;在pc1设备上ping ar2的地址&#xff0c;通过查看抓包信息&#xff0c;可以看到访问…

web安全学习笔记【21】——安全开发

安全开发-PHP应用&留言板功能&超全局变量&数据库操作&第三方插件引用 #知识点&#xff1a; 1、PHP留言板前后端功能实现 2、数据库创建&架构&增删改查 3、内置超全局变量&HTML&JS混编 4、第三方应用插件&传参&对象调用 DAY1 #章…

图解PyTorch中的torch.gather函数和 scatter 函数

前言 torch.gather在目前基于 transformer or query based 的目标检测中&#xff0c;在最后获取目标结果时&#xff0c;经常用到。 这里记录下用法&#xff0c;防止之后又忘了。 介绍 torch.gather 官方文档对torch.gather()的定义非常简洁 定义&#xff1a;从原tensor中获…

苹果App上架指南

苹果上架要求是苹果公司对于提交应用程序到苹果商店上架的要求和规定。这些要求主要是为了保证用户体验、应用程序的质量和安全性。以下是苹果上架要求的详细介绍&#xff1a;1. 应用程序的内容和功能必须符合苹果公司的规 苹果上架要求是苹果公司对于提交应用程序到苹果商店上…

iPhone设备中调试应用程序崩溃日志的高效方法探究

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么&#xff1f; 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志&#xff0c;以便调查崩溃的原因。我们将展示三种不同的…

基于YOLOv8的绝缘子检测系统

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;基于YOLOv8的绝缘子小目标检测&#xff0c;阐述了整个数据制作和训练可视化过程 1.YOLOv8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的&a…

iPhone设备中定位应用程序崩溃问题的日志分析技巧

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么&#xff1f; 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志&#xff0c;以便调查崩溃的原因。我们将展示三种不同的…

iPhone设备中通过开发者选项查看应用程序崩溃日志的实用技术

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么&#xff1f; 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志&#xff0c;以便调查崩溃的原因。我们将展示三种不同的…

[Rust开发]用可视化案例讲Rust编程6.动态分发与最终封装

全系列合集 [Rust开发]用可视化案例讲Rust编程1.用Rust画个百度地图 [Rust开发]用可视化案例讲Rust编程2. 编码的核心组成&#xff1a;函数 [Rust开发]用可视化案例讲Rust编程3.函数分解与参数传递 [Rust开发]用可视化案例讲Rust编程4.用泛型和特性实现自适配shapefile的读取 […

目标检测——服饰属性标签识别数据集

一、重要性及意义 首先&#xff0c;随着电商、时尚推荐等业务的发展&#xff0c;服饰属性标签识别已经成为一项关键的计算机视觉任务。这些标签&#xff0c;如颜色、款式、材质等&#xff0c;对于实现图像搜索、时尚推荐等业务需求至关重要。服饰属性标签识别数据集为此类任务…

用ChatGPT出题,完全做不完

最近小朋友正在学习加减法&#xff0c;正好利用ChatGPT来生成加减法练习题&#xff0c;小朋友表示够了&#xff0c;够了&#xff0c;完全做不完。本文将给大家介绍如何利用ChatGPT来生成练习题。 尚未获得ChatGPT的用户&#xff0c;请移步&#xff1a;五分钟开通GPT4.0。 角色…

谷粒商城实战(007 压力测试)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第141p-第p150的内容 简介 安装jmeter 安装jmeter 使用中文 这样写就是200个线程循环100次 一共是2万个请求 介绍线程组 添加请求 可以是htt…

设计模式之享元模式详解(下)

4&#xff09;完整解决方案-不带外部状态 1.结构图 IgoChessman充当抽象享元类&#xff0c;BlackIgoChessman和WhiteIgoChessman充当具体享元类&#xff0c;IgoChessmanFactory充当享元工厂类。 2.代码案例 抽象享元类 //围棋棋子类&#xff1a;抽象享元类 abstract class …

ES-7.12-官方文档阅读-ILM-Automate rollover

教程&#xff1a;使用ILM自动化滚动创建index 当你持续将带有时间戳的文档index到Elasticsearch当中时&#xff0c;通常会使用数据流&#xff08;data streams&#xff09;以便可以定义滚到到新索引。这是你能够实施一个hot-warm-cold架构来满足你的性能要强&#xff0c;控制随…

【单片机 5.3开关检测】

文章目录 前言一、5.3开关检测1.1没按键按下的1.2有按键按下的 二、改进1.改进 三、独立键盘3.1为什么要取反3.2 实用的按键 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 课程需要&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xf…

C++项目——集群聊天服务器项目(十一)服务器异常退出与添加好友业务

本节来实现C集群聊天服务器项目中的服务器异常退出与添加好友业务&#xff0c;一起来试试吧 一、服务器异常退出 在Linux环境下&#xff0c;我们在服务器端使用CTRLC结束程序执行&#xff0c;即使用CTRLC让服务器异常退出&#xff0c;这样的后果是本应登录服务器的用户在数据库…

2023年第十四届蓝桥杯 - 省赛 - Python研究生组 - A.工作时长

题目 数据文件&#xff1a;https://labfile.oss.aliyuncs.com/courses/21074/records.txt Idea 直接通过 datetime 模块加载时间字符串进行格式化&#xff0c;然后对时间列表进行排序&#xff0c;最后两两计算时间差。 Code Python from datetime import datetimetime_lis…

数论与线性代数——整除分块【数论分块】的【运用】【思考】【讲解】【证明(作者自己证的QWQ)】

文章目录 整除分块的思考与运用整除分块的时间复杂度证明 & 分块数量整除分块的公式 & 公式证明公式证明 代码code↓ 整除分块的思考与运用 整除分块是为了解决一个整数求和问题 题目的问题为&#xff1a; ∑ i 1 n ⌊ n i ⌋ \sum_{i1}^{n} \left \lfloor \frac{n}{…