Joy Interface

Overview

The raisin_joy_interface is an interface that receives multiple command source topics from a joystick connected to a robot or from a planning plugin. It manipulates these inputs into a single command message that is sent to the raisin_controller and outputs a ROS2 topic. Each command source topic has properties such as the topic name, priority, and a boolean variable called listen status. Except for a few exceptional cases, the interface outputs the message from the command source with the highest priority among those with listen status set to true. The command messages output by the interface are of two types:

  1. raisin/command: Commands the controller to move.

  2. raisin/joy_signal: Commands the transition of the phase or state of the motion.

Additionally, the interface includes safety features such as decaying the command to zero after a certain time if the joystick is disconnected, limiting the maximum rate of change of the desired velocity, and setting the listen status of a disconnected joystick to false. Command Source Types The command sources are divided into two types:

  1. JOY: Generated from a joystick.

  2. VEL_CMD: Generated from a plugin, external project…

To be understood by the joy_interface, the topic names must follow specific naming conventions:

  • JOY type topic names start with joy/….

  • VEL_CMD type topic names start with vel_cmd/….

Configuring Topics to Receive The potential topics and their priorities are defined in the params.yaml file of raisin_raibo2. Lower numbers indicate higher priority.

command_source_topics:
  value: ["joy/gui", "joy/rf", "vel_cmd/path_planning"]
  dtype: vector<string>

command_source_topic_priorities:
  value: [1, 0, 2]
  dtype: vector<int>

raisin/command Topic

The message type for the raisin/command topic is raisin_interfaces::msg::Command, which includes the following fields:

float64 x_pos
float64 y_pos
float64 x_vel
float64 y_vel
float64 yaw_rate

Currently, x_pos and y_pos are fixed at 0. The x_vel, y_vel, and yaw_rate correspond to axes 0, 1, and 2 of the sensor_msgs::msg::Joy message generated by the joystick.

raisin/joy_signal Topic

The message type for the joy_signal topic is std_msgs::msg::Int16. Each value corresponds to a specific signal defined in the JoySignal class. This message is generated only by JOY type command sources. The buttons 0, 1, 2, and 3 of the sensor_msgs::msg::Joy message correspond to the HALT, LISTEN, ACTION0, and ACTION1 signals, respectively.

  • HALT: Transitions the robot’s state to MOTOR_DISABLED.

  • LISTEN: Changes the listen status of the command source.

  • ACTION0 and ACTION1: Can be customized to change the phase in the controller.

enum class JoySignal : int {
  SIGHALT = 0,
  SIGLISTEN,
  SIGACTION0,
  SIGACTION1,
  NUM_JOY_SIGNALS
};

Parameters of raisin_joy_interface (params.yaml)

  • joy_allowable_delay_time: If no communication is received from the joystick for this duration (in seconds), the command starts to decay.

  • joy_axes_to_zero_time: The time (in seconds) it takes to decay the command to zero after starting the decay process.

# Safety settings
joy_allowable_delay_time:
  value: 0.5
  dtype: double

joy_axes_to_zero_time:
  value: 0.5
  dtype: double
  • command_allowable_accel: Defines the maximum rate of change per unit time for the desired velocity commands (x_vel, y_vel, yaw_rate).

command_allowable_accel:
  value: [8.0, 4.0, 4.0]
  dtype: vector<double>
  • listen_default_status: Defines the default listen status for each topic when the Raibo_node starts (default: false).

  • unintended_signal_guard_max_count: To prevent erroneous values from a communication error, the same button must be pressed multiple times to send a JoySignal. This count is defined here.

joy/gui:
  listen_default_status:
    value: true
    dtype: bool
  unintended_signal_guard_max_count:
    value: 0
    dtype: int

Code Example

The example code is available in https://github.com/railabatkaist/raisin_examples.git.

This example illustrates a basic approach to robot control using the joyinterface.

  • The joy_interface_example node communicates with the joyinterface by publishing command type messages, allowing cmd_vel input to be translated into robot motion.

Important: you need to add the topic “vel_cmd/simple” to the command_source_topics in the raibo2 config

joy_interface_example

source code

//
// Created by user on 25. 7. 29.
//
#include "raisin_network/network.hpp"
#include "raisin_network/node.hpp"
#include "raisin_interfaces/msg/command.hpp"
#include "raisin_interfaces/srv/string.hpp"
#include "raisin_interfaces/srv/string_and_bool.hpp"
#include "raisin_network/raisin.hpp"
#include "std_srvs/srv/trigger.hpp"
#include "raisin_interfaces/msg/velocity_command.hpp"
#include <thread>
using namespace raisin;



int main(int argc, char * argv[])
{
  raisinInit();
  std::string clientId = "joy_interface_example";
  // Instantiate the raisin::Network object as a client
  std::vector<std::vector<std::string>> threads = {{"main"}};
  std::shared_ptr<raisin::Network> network = std::make_shared<raisin::Network>(
          clientId,
          "cmd",
          threads);
  std::this_thread::sleep_for(std::chrono::seconds(3));
  raisin::Node node(network);

  std::string id = "railab_raibo"; // your raibo2_node nickname
  auto connection = network->connect(id);

  std::shared_ptr<raisin::Client<raisin_interfaces::srv::String>> client_ = node.createClient<raisin_interfaces::srv::String>("set_listen", connection, "client");
  auto request_ = std::make_shared<raisin_interfaces::srv::String::Request>();
  request_->data = "vel_cmd/simple";
  auto result_ = client_->asyncSendRequest(request_);

  std::this_thread::sleep_for(std::chrono::seconds(1));

  raisin_interfaces::msg::VelocityCommand cmd;
  auto publisher = node.createPublisher<raisin_interfaces::msg::VelocityCommand>("vel_cmd/simple");

  //you need to add the topic "vel_cmd/simple" to the command_source_topics in the raibo2 config
  while (true) {
    cmd.x_vel = 0;
    cmd.y_vel = 0;
    cmd.yaw_rate = 1;
    publisher->publish(cmd);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
  }
  return 0;
}

build

cd joy_interface_example
mkdir build && cd build
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release
ninja -j8

run the node

source $RAISIN_WS/ld_prefix_path.sh
./joy_interface_example

As a result, the robot will rotate with 1rad/s speed.

This example performs:

  • connect to raisin_raibo2 node: the id of the node is “railab_raibo” in this case.

  • set_listen: Configures the robot to use control values from the topic “vel_cmd/simple”.

  • vel_cmd: Publishes control values to enable the robot to move based on the given commands.

For details about each service node and client node, please refer to the Network section.