Visualization
Obelisk comes with a suite of tools for visualizing the robot. Some of these include:
Robot visualization nodes to display robots in Rviz or Foxglove
Robot Visualization
Oftentimes you may want to display a visual of a robot in a specified configuration, or see the motion of a robot throughout a trajectory, or maybe you want to check the estimated state vs the true state. In all of these cases we need to be able to see the robot. Obelisk provides two nodes to help with this:
ObeliskVizRobotwhich is an abstract class, designed to be inheritedObeliskVizRobotDefaultwhich is a concrete child ofObeliskVizRobotdesigned to work with most common estimated message types
These nodes are designed to run while estimated state messages are being published. They can be configured to listen to any chosen topic. Once listening to this topic, they will parse incoming estimated state messages into a format that the visualizer understands. Concretely, this means that the estimated state is being transformed into a sensor_msgs/msg/JointState message and a tf2 transform between the fixed frame (default is world) and the base link on the robot. The JointState message is being published so that a robot_state_publisher (see here) can transform it into the transforms needed by Rviz.
With the proper configuration settings, the launch file will automatically bring up Rviz (with the desired configuration file), bring up the robot_state_publisher and the ObeliskVizRobot. Multiple robots can be brought up by specifying multiple ObeliskVizRobots.
In most cases, ObeliskVizRobotDefault should work fine. ObeliskVizRobotDefault requires an estimated state message with the following fields:
base_link_name: name of the base linkq_base: vector of (x, y, z, quat_x, quat_y, quat_z, quat_w). If length is zero then we assume the robot is fixed basejoint_names: names of all the jointsq_joints: vector of joint positions
The base_link_name must match a link in the URDF and joint_names must all be valid joint names in the URDF. If the estimated message does not have these fields, then you must extend ObeliskVizRobot and write the code to parse the message into the necessary transform and message.
Visualization Configuration Settings
Example Configuration
viz:
on: True
viz_tool: rviz
rviz_pkg: obelisk_ros
rviz_config: basic_obk_config.rviz
viz_nodes:
- pkg: obelisk_viz_cpp
executable: default_robot_viz
robot_pkg: g1_description
urdf: g1.urdf
robot_topic: robot_description
tf_prefix: g1
subscribers:
- ros_parameter: sub_viz_est_setting
topic: estimated_state
history_depth: 10
callback_group: None
non_obelisk: False
publishers:
- ros_parameter: pub_viz_joint_setting
topic: joint_states_g1
history_depth: 10
callback_group: None
timers:
- ros_parameter: timer_viz_joint_setting
timer_period_sec: 0.05
callback_group: None
- pkg: obelisk_viz_cpp
executable: default_robot_viz
robot_pkg: go2_description
urdf: go2_description.urdf
robot_topic: go2_description
tf_prefix: go2
subscribers:
- ros_parameter: sub_viz_est_setting
topic: estimated_state2
history_depth: 10
callback_group: None
non_obelisk: False
publishers:
- ros_parameter: pub_viz_joint_setting
topic: joint_states_go2
history_depth: 10
callback_group: None
timers:
- ros_parameter: timer_viz_joint_setting
timer_period_sec: 0.05
callback_group: None
Breaking Down the Configuration
viz:
on: True
rviz_pkg: obelisk_ros
rviz_config: basic_obk_config.rviz
The visualization section starts with the viz tag. Then we have all the “global” visualization settings, i.e., all the settings that apply to everything, such as Rviz settings.
onis a boolean flag to turn on or off the visualizer and spin the nodes. If this is false, all the following settings are skipped.viz_tool(optional) selects which visualization tool to bring up. For now the only two supported options arervizandfoxglove. If not present, the default isrviz.rviz_pkg(optional) is the package where the Rviz configuration file is found. Not need ifviz_toolisfoxglove, but required forrviz.rviz_config(optional) is the name of the Rviz configuration file. Note that we assume this is stored in a folder namedrvizin the package listed above. Be sure that this folder is “installed” when building ROS. Not need ifviz_toolisfoxglove, but required forrviz.
Then, under viz_nodes we have a list of nodes and their settings. We will examine only one as they always have the same fields.
- pkg: obelisk_viz_cpp
executable: default_robot_viz
robot_pkg: g1_description
urdf: g1.urdf
robot_topic: robot_description
tf_prefix: g1
subscribers:
- ros_parameter: sub_viz_est_setting
topic: estimated_state
history_depth: 10
callback_group: None
non_obelisk: False
publishers:
- ros_parameter: pub_viz_joint_setting
topic: joint_states_g1
history_depth: 10
callback_group: None
timers:
- ros_parameter: timer_viz_joint_setting
timer_period_sec: 0.05
callback_group: None
pkggives the package where the executable is.executableis the name of the executable.robot_pkgis the name of the package where all the robot files are stored.urdfis the name of the URDF file. Note that we assume the urdf is stored in a folder namedrvizin therobot_pkg.robot_topic(optional) is the name of the topic where the robot description (urdf) will be published for Rviz. This remaps therobot_descriptiontopic give in therobot_state_publisher.tf_prefix(optional) is the prefix on all of the transform messages put out by therobot_state_publisher. In theObeliskVizRobotDefaultimplementation this is accounted for. If you extendObeliskVizRobotmanually, then you must be sure to use this prefix (given as a node parameter) to prefix the base transform.Finally we have all the normal component settings, which we will not go over here.
The robot_topic and tf_prefix are mostly useful when you have multiple robots to display. By changing these options we can prevent name clashes.
Implementing a Custom Robot Visualization
To implement a custom visualization, you must write code that inherits from ObeliskVizRobot. The source code for ObeliskVizRobotDefault should act as a guide. Specific todo items are listed here:
Inherit from
ObeliskVizRobotImplement the
ParseEstimatedStateMessagefunction. In this function, you must:Fill in
joint_state_with the robot’s joint state information.Fill in
base_tf_with the transform from the fixed frame (normally called “world”) to the base link on the robot.You should support publishing the transform with a specific tf prefix, which you can access through the ROS parameter
tf_prefix.You should verify the contents of the message and print helpful warning messages if the message is not correct.