0
$\begingroup$

I'm completely new to ROS(2) and I want to make my Robot Model in RViz move depending on sensordata. I build my files according to a minimal working example from youtube and it allows me to visualize my project in RViz an manipulate the joint with the joint_state_publisher with my computermouse, but I want to make it subscribe to sensordata, therefore I tried to manipulate the joint using:

ros2 topic pub /tf tf2_msgs/msg/TFMessage '{transforms: [{header: {stamp: {sec: 0, nanosec: 0}, frame_id: "start_frame"}, child_frame_id: "end_frame", transform: {translation: {x: 1.0, y: 2.0, z: 2.0}, rotation: {x: 0.0, y: 0.0, z: 0.0, w: 0.5}}}]}' 

in the Terminal and I when I subscribe to the joint_state_publisher_gui I can see, that the values change accordingly for a fraction of a second but are then overwritten again from the joint_state_publisher.

CMakeLists.txt:

    cmake_minimum_required(VERSION 3.8)
project(smartjig_urdf)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)

    #selbst hinzugefügt, zur Not entfernen
        find_package(ament_cmake_python REQUIRED)    
        find_package(rclpy REQUIRED)
    #selbst hinzugefügt, zur Not entfernen



install(
    DIRECTORY launch urdf
    DESTINATION share/${PROJECT_NAME}
    )

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

display.launch.py:

import launch
from launch.substitutions import Command, LaunchConfiguration
import launch_ros
import os

def generate_launch_description():
    pkgPath = launch_ros.substitutions.FindPackageShare(package='smartjig_urdf').find('smartjig_urdf')
    urdfModelPath= os.path.join(pkgPath, 'urdf/smartjig.urdf')
    
    with open(urdfModelPath,'r') as infp:
        robot_desc = infp.read()
        
    params = {'robot_description': robot_desc}
    
    robot_state_publisher_node =launch_ros.actions.Node(
    package='robot_state_publisher',
    executable='robot_state_publisher',
    output='screen',
    parameters=[params])
    
    joint_state_publisher_node = launch_ros.actions.Node(
        package='joint_state_publisher',
        executable='joint_state_publisher',
        name='joint_state_publisher',
        parameters=[params],
        condition=launch.conditions.UnlessCondition(LaunchConfiguration('gui'))
    )
    joint_state_publisher_gui_node = launch_ros.actions.Node(
        package='joint_state_publisher_gui',
        executable='joint_state_publisher_gui',
        name='joint_state_publisher_gui',
        condition=launch.conditions.IfCondition(LaunchConfiguration('gui'))
    )
    
    rviz_node = launch_ros.actions.Node(
        package='rviz2',
        executable='rviz2',
        name='rviz2',
        output='screen'
    )
    
    return launch.LaunchDescription([
        launch.actions.DeclareLaunchArgument(name='gui', default_value='True',
                description='This is a flag for joint_state_publisher_gui'),
        launch.actions.DeclareLaunchArgument(name='model', default_value=urdfModelPath,
                description='Path to the urdf model file'),
    robot_state_publisher_node,
    joint_state_publisher_node,
    joint_state_publisher_gui_node,
    rviz_node
    ])

package.xml:

import launch
from launch.substitutions import Command, LaunchConfiguration
import launch_ros
import os

def generate_launch_description():
    pkgPath = launch_ros.substitutions.FindPackageShare(package='smartjig_urdf').find('smartjig_urdf')
    urdfModelPath= os.path.join(pkgPath, 'urdf/smartjig.urdf')
    
    with open(urdfModelPath,'r') as infp:
        robot_desc = infp.read()
        
    params = {'robot_description': robot_desc}
    
    robot_state_publisher_node =launch_ros.actions.Node(
    package='robot_state_publisher',
    executable='robot_state_publisher',
    output='screen',
    parameters=[params])
    
    joint_state_publisher_node = launch_ros.actions.Node(
        package='joint_state_publisher',
        executable='joint_state_publisher',
        name='joint_state_publisher',
        parameters=[params],
        condition=launch.conditions.UnlessCondition(LaunchConfiguration('gui'))
    )
    joint_state_publisher_gui_node = launch_ros.actions.Node(
        package='joint_state_publisher_gui',
        executable='joint_state_publisher_gui',
        name='joint_state_publisher_gui',
        condition=launch.conditions.IfCondition(LaunchConfiguration('gui'))
    )
    
    rviz_node = launch_ros.actions.Node(
        package='rviz2',
        executable='rviz2',
        name='rviz2',
        output='screen'
    )
    
    return launch.LaunchDescription([
        launch.actions.DeclareLaunchArgument(name='gui', default_value='True',
                description='This is a flag for joint_state_publisher_gui'),
        launch.actions.DeclareLaunchArgument(name='model', default_value=urdfModelPath,
                description='Path to the urdf model file'),
    robot_state_publisher_node,
    joint_state_publisher_node,
    joint_state_publisher_gui_node,
    rviz_node
    ])

smartjig.urdf:

import launch
from launch.substitutions import Command, LaunchConfiguration
import launch_ros
import os

def generate_launch_description():
    pkgPath = launch_ros.substitutions.FindPackageShare(package='smartjig_urdf').find('smartjig_urdf')
    urdfModelPath= os.path.join(pkgPath, 'urdf/smartjig.urdf')
    
    with open(urdfModelPath,'r') as infp:
        robot_desc = infp.read()
        
    params = {'robot_description': robot_desc}
    
    robot_state_publisher_node =launch_ros.actions.Node(
    package='robot_state_publisher',
    executable='robot_state_publisher',
    output='screen',
    parameters=[params])
    
    joint_state_publisher_node = launch_ros.actions.Node(
        package='joint_state_publisher',
        executable='joint_state_publisher',
        name='joint_state_publisher',
        parameters=[params],
        condition=launch.conditions.UnlessCondition(LaunchConfiguration('gui'))
    )
    joint_state_publisher_gui_node = launch_ros.actions.Node(
        package='joint_state_publisher_gui',
        executable='joint_state_publisher_gui',
        name='joint_state_publisher_gui',
        condition=launch.conditions.IfCondition(LaunchConfiguration('gui'))
    )
    
    rviz_node = launch_ros.actions.Node(
        package='rviz2',
        executable='rviz2',
        name='rviz2',
        output='screen'
    )
    
    return launch.LaunchDescription([
        launch.actions.DeclareLaunchArgument(name='gui', default_value='True',
                description='This is a flag for joint_state_publisher_gui'),
        launch.actions.DeclareLaunchArgument(name='model', default_value=urdfModelPath,
                description='Path to the urdf model file'),
    robot_state_publisher_node,
    joint_state_publisher_node,
    joint_state_publisher_gui_node,
    rviz_node
    ])
$\endgroup$

2 Answers 2

0
$\begingroup$

If you want to change those values, you'd need to stop the joint state publisher so that you can override them in rviz. Keep in mind Rviz is just a visualizer, its not a simulator like gazebo. Its only showing you what's going on over the messages / transforms.

Most practically, you'd want to make your own joint state publisher script so that you can manipulate it if you want to move it (visually speaking). I believe there are examples of this in MoveIt where they have sliders that you can move joints in an arm with a QT application to make your robot do something in an Rviz display. But obviously this is just one example, you're free and encouraged to do something more specific for your needs / tests.

$\endgroup$
0
$\begingroup$

You'd want to write a ROS node that reads in your sensor data with a joint states publisher. Based off your sensor reading, you can publish the joint behavior you'd like. Then replace your joint_state_publisher and joint_state_publisher_gui nodes in launch file with this node you just made.

They'll be tutorials in the ROS documentation but here are the key parts to having a custom joint state publisher:

custom_jsp = this->create_publisher<sensor_msgs::msg::JointState>(
        "topic_name",
        rclcpp::QoS(1));
sensor_msgs::msg::JointState joint_states_msg;
joint_states_msg.header.stamp = this->get_clock()->now();
joint_states_msg.name = {
    "link_name", // That matches your robot_description
};
joint_states_msg.position = {
    0.0, // Position effected by sensor data, from another loop in your node
};
custom_jsp->publish(joint_states_msg);

Let me know if this helps!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.