【问题标题】:Subscriber to Joy Topic in ROSROS中Joy主题的订阅者
【发布时间】:2020-10-29 02:57:11
【问题描述】:

我想将我的 XBOX 游戏手柄集成到 ROS 中。

这个想法是写一个订阅者到主题“/joy”并获取每个按钮和每个轴的数据,以便我可以使用它们来控制我的机器人。

我遵循了本教程:“http://wiki.ros.org/joy/Tutorials/WritingTeleopNode”并且我想对其进行编辑。但他们只从轴心国获取信息。我也想从按钮中获得。

另外,我不想将这些消息作为 Twist 消息发布到海龟节点。我想将它们发送到一个新主题。

对于此类问题,我可以提供一些帮助或链接到已经完成的软件包吗?

【问题讨论】:

  • 我认为这是this SO的延续
  • 您好,是的。感谢最后的提示!但我稍后需要实时连接,我不想使用 ROS-Simulink 连接,因为它不具备实时功能。所以我会设法在 ROS 中拥有这一切。

标签: ros robot xbox


【解决方案1】:

当您订阅sensor_msgs/joy 消息时,您将拥有一个float32[] axes 和一个int32[] buttons。在您的节点中主题的回调中,您可以访问 msg 的成员。数组是 python 中的列表和 C++ 中的向量。经典的两种范例是从回调中发布新的 msg,在回调中进行转换,和/或将回调中的数据存储为全局变量,以用于另一个 msg 回调或计时器/定期回调。

但是,您仍然需要弄清楚哪些按钮映射到数组中的哪个数字元素。请参阅joy_node docsjstest/jstest-gtk 中的正常编号以获取相关帮助;将映射存储为相关的枚举。

最小示例:

// joy_to_something_node.cpp

// ROS
#include <ros/ros.h>
#include <sensor_msgs/Joy.h>
#include <std_msgs/Bool.h>
#include <geometry_msgs/Vector3Stamped.h>

// Std Libs
#include <vector>
#include <stdint.h>

// Subscribers
//   joy_sub (sensor_msgs/Joy): "joy"

// Publishers
//   estop_pub (std_msgs/Bool): "estop"
//   btn_dir_pub (geometry_msgs/Vector3Stamped): "joy/btn_dir"

// Parameters
//   frequency (double): 10 Hz
//   lag (double): 0.25 %
//   // could have the mappings as params

enum {
  JOY_BTN_A = 0,
  JOY_BTN_B = 1,
  JOY_BTN_X = 2,
  JOY_BTN_Y = 3,
  JOY_BTN_LB = 4,
  JOY_BTN_RB = 5,
};

// ROS Nodehandles and Publishers
ros::NodeHandle *nh;
ros::NodeHandle *pnh;
ros::Publisher estop_pub;
ros::Publisher btn_dir_pub;

// ROS Callbacks
void joy_cb(const sensor_msgs::Joy::ConstPtr& msg);
void timer_cb(const ros::TimerEvent&);

// ROS Params
double frequency = 10.0;
double lag = 0.25;

// Globals (ex)
std::vector<int32_t> btn_dir_data;
geometry_msgs::Vector3Stamped btn_dir_msg;

int main(int argc, char** argv){
  // Init
  ros::init(argc, argv, "joy_to_something_node");
  nh = new ros::NodeHandle();
  pnh = new ros::NodeHandle("~");

  pnh->getParam("frequency", frequency);
  pnh->getParam("lag", lag);

  btn_dir_msg.header.frame_id = "base_link";

  // Subs
  ros::Subscriber joy_sub = nh->subscribe("joy", 1, joy_cb);
  ros::Timer timer = nh->createTimer(ros::Duration(1.0/frequency), timer_cb);

  // Pubs
  estop_pub = nh->advertise<std_msgs::Bool>("estop", 1);
  btn_dir_pub = nh->advertise<geometry_msgs::Vector3Stamped>("joy/btn_dir", 1);

  // Exec
  ros::spin();
  return 0;
}

void joy_cb(const sensor_msgs::Joy::ConstPtr& msg){
  std_msgs::Bool estop_msg;
  estop_msg.data = msg->buttons[JOY_BTN_LB] > 0; // Should be 1 or zero
  estop_pub.publish(estop_msg);

  btn_dir_data = msg->buttons;
}

void timer_cb(const ros::TimerEvent&){
  btn_dir_msg.header.seq++;
  btn_dir_msg.header.stamp = ros::Time::now();
  // X is fwd, Y is right
  btn_dir_msg.vector.x *= lag;
  btn_dir_msg.vector.x += (1.0 - lag) * (btn_dir_data[JOY_BTN_Y] - btn_dir_data[JOY_BTN_A]);
  btn_dir_msg.vector.y *= lag;
  btn_dir_msg.vector.y += (1.0 - lag) * (btn_dir_data[JOY_BTN_B] - btn_dir_data[JOY_BTN_X]);
  btn_dir_pub.publish(btn_dir_msg);
}

我的 CMakeLists.txt 通常有这些:

find_package(catkin REQUIRED
    roscpp
    cmake_modules
    std_msgs
    geometry_msgs
)

catkin_package(
  INCLUDE_DIRS include 
#  LIBRARIES [custom libs]
  CATKIN_DEPENDS
    roscpp
    std_msgs
    nav_msgs
#  DEPENDS [sys libs]
)

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

add_executable(my_node src/my_node.cpp)
target_link_libraries(my_node ${catkin_LIBRARIES})
set_target_properties(my_node PROPERTIES COMPILE_FLAGS "${CPP_DEVEL_FLAGS}")

同样,您的 package.xml 依赖可以只是您也放入 CMakeLists.txt 中的那些,如果您使用(现代)格式=2,则不需要多个声明。

<buildtool_depend>catkin</buildtool_depend>
<depend>roscpp</depend>
<depend>geometry_msgs</depend>
<depend>std_msgs</depend>

编辑:添加说明和 cmake/package.xml。

【讨论】:

  • 它有效,但我将ros::now() 更改为ros::Time::now()btn_dir_msg.header.frame 出现错误,我将其更改为 btn_dir_msg.header.frame_id,最后 ros::spin() 需要 ;。然后一切正常。非常感谢。解决方案奏效了。
猜你喜欢
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 2016-02-07
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多