ROS 北通游戏手柄灵敏度 频率过高, xbox360/ ps2/3模式切换问题

6 篇文章 0 订阅

问题现象

第一批买的ROS手柄存在问题:
1.不能自动关机,导致耗电量大,一天1充/2充
2.不同手柄一致性不一样,右摇杆上下方向,键值不一样

之前用过北通游戏手柄,感觉比较好用,项目中买一个无线版测试,验证.

遇到问题

1.问题1: 开发板无法识别input设备, /dev/input/jsx 枚举失败.
解决方法:ubuntu/linux 北通无线游戏手柄不识别
2.问题2: 北通游戏手柄 左右摇杆 灵敏度/频率过高
在这里插入图片描述

实测: 左右摇杆输出频率达到100Hz
rosrun joy joy_node
rostopic hz /joy

subscribed to [/joy]
average rate: 152.672
min: 0.001s max: 0.107s std dev: 0.01296s window: 81
average rate: 162.566
min: 0.001s max: 0.107s std dev: 0.01199s window: 241
average rate: 131.580
min: 0.001s max: 0.247s std dev: 0.02013s window: 308

尝试解决方案

1.咨询北通官方技术支持,修改灵敏度. --NG, 本款手柄不支持修改灵敏度.
2.修改joy_node参数 --OK
3.修改源码 --OK

方法1:修改joy_node参数

<launch>
    <!--手柄控制-->
    <node pkg="joy" name="joy_node" type="joy_node" output = "screen">
        <param name="coalesce_interval" value="0.2" type="double"/>
    </node>
</launch>

代码原理:
github搜索: joystick_drivers joy github代码链接
joy_node.cpp

	nh_param.param<double>("coalesce_interval", coalesce_interval_, 0.001); #launch 修改此参数
	
        bool publish_now = false;
        bool publish_soon = false;
		int select_out = select(joy_fd+1, &set, nullptr, nullptr, &tv);
          if (read(joy_fd, &event, sizeof(js_event)) == -1 && errno != EAGAIN)
          {
            break;  // Joystick is probably closed. Definitely occurs.
          }
		  
        if (publish_now)
        {
          // Assume that all the JS_EVENT_INIT messages have arrived already.
          // This should be the case as the kernel sends them along as soon as
          // the device opens.
          joy_msg.header.stamp = ros::Time().now();
          joy_msg.header.frame_id = joy_dev_.c_str();
          pub_.publish(joy_msg);

          publish_now = false;
          tv_set = false;
          publication_pending = false;
          publish_soon = false;
          pub_count_++;
        }
		
        if (!publication_pending && publish_soon)
        {
          tv.tv_sec = trunc(coalesce_interval_);
          tv.tv_usec = (coalesce_interval_ - tv.tv_sec) * 1e6;
          publication_pending = true;
          tv_set = true;
        }

逻辑概要:
话题发布频率 --> select超时 -->
tv_set —> publication_pending --> publish_now --> 话题发布pub_.publish(joy_msg)

逻辑有点复杂,我是通过vscode + gdb调试, 在变量变化处加断点, 才理清逻辑.

实测结果:
rostopic hz /joy

rostopic hz /joy
average rate: 9.589
min: 0.102s max: 0.110s std dev: 0.00286s window: 6
average rate: 9.558
min: 0.101s max: 0.115s std dev: 0.00433s window: 10
average rate: 6.923
min: 0.101s max: 0.833s std dev: 0.16693s window: 19

频率限制到10Hz

方法2.其它参数尝试

修改autorepeat_rate

<launch>
  <node pkg="joy_test" name="joy_node" type="joy_node">
    <param name="autorepeat_rate" value="0.1" type="doble"/>
  </node>
</launch>
nh_param.param<double>("autorepeat_rate", autorepeat_rate_, 0);

实测结果: --NG
输出频率是10Hz, 不过由于input缓冲区问题, 停止拨动手柄摇杆, 依旧会继续输出,10s之后才停止.

方法3.自己修改源码

joy_node.cpp gitee修改代码
核心代码实现

  bool check_publish_time()
  {
    double now_time = ros::Time::now().toSec();
    if ((now_time - pub_time_) > pub_delay_)
    {
      pub_time_ = now_time;
      return true;
    }

    return false;
  }

main()
{
read_joy:
          if (read(joy_fd, &event, sizeof(js_event)) == -1 && errno != EAGAIN)
          {
            break;  // Joystick is probably closed. Definitely occurs.
          }

          if (check_publish_time() == false)
            goto read_joy;
}

通过函数 check_publish_time() 检查发布时间,如果时间差小于0.1s, 继续read (清空缓冲区)

注意事项:
一定要继续read(), 清空input buffer缓冲区, 不然会出现 方法2 一样的现象, 停止拨动手柄摇杆, 继续输出.

xbox360 ps2/3模式切换方法

长按北通Logo 切换模式
在这里插入图片描述

总结:

  1. 目前只是限制ros topic 发布频率, 没有从根本上解决问题, 后面尝试添加sys节点, 从kernel限制频率.
  2. 运到问题,大部分还是得从源码方面解决问题, 定制需求.

我是一名ROS机器人,嵌入式开发工程师

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值