Question:
Convert ROS2 SQLite bag to MCAP format
Asked 5 months ago
Modified 5 months ago
Viewed 803 times
2

I've got some ROS2 bags in SQLite format that I'd like to convert to MCAP format, but I cannot find any examples or tools that do it. I'd have hoped there would be an obvious option for ros2 bag convert, like the --output-options YAML's storage_id:, but it's not obvious to me what to use.

Explanation: SQLite files usually end with .db3. The steps about convert your existing ROS 2 .db3 files into MCAP files using ros2 bag convert would be related.

$\begingroup$

I did this recently with the mcap cli tool built from source [
https://github.com/foxglove/mcap ](https://github.com/foxglove/mcap) :

    sudo apt install golang-go
    git clone [[email protected]](/cdn-cgi/l/email-protection):foxglove/mcap.git
    cd mcap/go
    make -C cli/mcap build
    ./cli/mcap/bin/mcap version  # show the binary works

After that you need to have all the message definitions of all the messages in
the .db3 file available, source the workspace they were built in (e.g. `
source /opt/ros/humble/setup.bash ` works if using ` humble ` and all of the
required messages were apt installed, or ` source
~/my_ros2_ws/install/setup.bash ` if you had to build some packages with
custom messages):

    source your_ros2_ws/install/setup.bash
    cd directory_with_db3
    # I made a symlink to ./mcap/go/cli/mcap/bin/mcap so it is on my PATH
    mcap convert foo.db3 foo.mcap
    # see that all the messages are there
    mcap info foo.mcap
    library:   mcap go v1.0.4
    profile:   ros2
    messages:  834056
    duration:  9m38.219675178s
    start:     2022-01-07T12:39:35.007852857-08:00 (1641587975.007852857)
    end:       2022-01-07T12:49:13.227528035-08:00 (1641588553.227528035)
    compression:
        zstd: [1834/1834 chunks] [15.58 GiB/10.90 GiB (30.03%)] [19.31 MiB/sec]
    channels:
    ...

There's an example mcap I made (and also used ` mcap filter ` to reduce the
size) attached to the issue here (and a workaround to related issue with
viewing the mcap in plotjuggler): [
https://github.com/facontidavide/PlotJuggler/issues/878
](https://github.com/facontidavide/PlotJuggler/issues/878)

##  mcap convert while missing messages

    ...failed to convert file: failed to find schema for novatel_oem7_msgs/msg/BESTVEL: schema not found

It exits immediately on encountering an unknown message and leaves behind an
mcap file of size 0.

#  ros2 bag convert

ros2 bag convert also works (going from [ https://mcap.dev/guides/getting-
started/ros-2#using-ros2-bag-convert ](https://mcap.dev/guides/getting-
started/ros-2#using-ros2-bag-convert) ), at least with the ros2 bag I built
from iron sources:

convert.yaml:

    output_bags:
      - uri: ros2_output
        storage_id: mcap
        all: true

The uri is the output directory the mcap conversion will be stored in, it
doesn't look possible to specify it on the command line as with the ` mcap `
tool. More possible parameters for the yaml are listed in [
https://github.com/ros2/rosbag2#converting-bags
](https://github.com/ros2/rosbag2#converting-bags) but not documented.

    ros2 bag convert -i E-SOLO-FAST-140-170.db3 -o ../../../convert.yaml

    closing.

    closing.
    [INFO] [1698332502.004769814] [rosbag2_storage]: Opened database 'E-SOLO-FAST-140-170.db3' for READ_ONLY.

It creates a subdirectory ` ros2_output/ ` with ` metadata.yaml ` and `
ros2_output_0.mcap ` (now format ` libmcap 0.8.0 ` ), looks to have all the
messages in it.

##  ros2 bag convert while missing messages

    ros2 bag convert -i . -o ../../../convert.yaml
    ^C[INFO] [1698419071.371486821] [rosbag2_storage]: Opened database './T-MULTI-FAST-EURO.db3' for READ_ONLY.
    [WARN] [1698419071.444842070] [ROSBAG2_TRANSPORT]: Topic '/vehicle_3/radar_front/esr_status1' has unknown type 'delphi_esr_msgs/msg/EsrStatus1' . Only topics with known type are supported. Reason: 'package 'delphi_esr_msgs' not found, searching: [/home/lucasw/ros/ros2_iron/install/rqt_bag_plugins, /home/lucasw/ros/ros2_iron/install/rosbag2,

In contrast with ` mcap ` the ` ros2 bag convert ` converts every message it
does understand and skips the rest.

##  ros2 bag zstd compression

These compression options can be added to convert.yaml, but the output `
.mcap.zstd ` file is not readable by the mcap cli tool (while ros2 bag info
works with it):

        compression_mode: file
        compression_format: zstd

This yields mcap files readable by the mcap tool but the files are a little
larger, appears to be the same as the default settings of the mcap cli tool:

        compression_mode: message
        compression_format: zstd


Question:
About Lifecycle, And how to call `on_deactivate()` in `hardware_interface` of ros2_control by controller_manager CLI or other method?

I have implemented a hardware interface in ros2_control and added code to free my hardware resources in the on_deactivate() method.

When I try to stop the controller with the command ros2 control set_controller_state diffbot_base_controller inactive and try to free the hardware, on_deactivate() doesn't seem to be called.

I can't find console output from deactivate, and the read/write method is still being called. Unlike before, only the value from hw_command_ is 0.

It's very confusing.Maybe I'm confused about the life cycle concept in controller_manager of ros2_control. I was hoping to get some tips or links to relevant materials.

Explanation:
The hardware components and controllers may be different in ros2_control. Deactivating the controller may not guarantee the deactivation of the hardware component.

We can check some discussion about the Lifecycle of hardware components.

$\begingroup$

Be aware that hardware components and controllers are different parts of
ros2_control. You try to deactivate the controller -> this does not deactivate
the hardware component.

Lifecycle of hardware components is not 100% implemented as by now, and there
[ are some issues ](https://github.com/ros-controls/ros2_control/issues/1103)
with the current implementation. Moreover, controller won't be deactivated
currently if you deactivate the hardware_component, where the controller
claimed the interfaces.

Have a look at [ this draft example ](https://github.com/StoglRobotics-
forks/ros2_control_demos/pull/7) , which should make things more clear.


Question:
How do I send a new position to my 5 dof robot arm?

I am a newbie with ros2 control. I am using ros2 iron on Ubunto 22.04 (Linux Mint). I made a copy of the ros2_control demo example #7.

This is the one that is launched with the command ros2 launch ros2_control_demo_example_7  r6bot_controller.launch.py, I changed the name as well as urdf file. I also interfaced it with my Arduino robot arm based on positions. My arm has 5 instead of 6 joints and only uses positions. There are no encoders on my arm. All the velocity commands and states related to velocity were taken out of example 7. In my hardware interface (copy), I have code that when a position is changed, the code should send off a state change to an Arduino robot arm...

When I run ros2 control list_controllers, I see

jem_5dof_robot_arm_controller[jem_robot_arm/RobotController] active
joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
When I run ros2 control list_hardware_interfaces, I see

command interfaces
    Joint1/position [available] [claimed]
    Joint2/position [available] [claimed]
    Joint3/position [available] [claimed]
    Joint4/position [available] [claimed]
    Joint5/position [available] [claimed]
state interfaces
    Joint1/position
    Joint2/position
    Joint3/position
    Joint4/position
    Joint5/position
I also see am image of my robot arm in rviz... I would say "things look like they are working"

My question is this...........

How do I send a new position to my robot arm from the command line or a GUI. Either send one new position for a Joint or send the set of positions for all 5 joints. All I want to happen is, quickly send something and interact with the Arduino hardware. I believe the code I implemented in the hardware interface to my Arduino based arm will work, the question is how to I force something to call my hardware interface with an update (so as to test). I'd like to set a few different positions and see if the hardware is working ok. Ideally, it would be nice to make changes in rviz and send those changes to my arm/Arduino. I suspect that rviz is only a one way visualization of the arm and has no way to move something. I suspect that once a new position is sent to my robot arm's controller [jem_5dof_robot_arm_controller], rviz will update accordingly.

What are is a simple way to send off a few new positions from the command line to test?

Explanation: The custom controller may not be required. We may find information about position controller.

$\begingroup$

The first question: do you really need a custom controller, or might work a [
position_controller
](https://control.ros.org/master/doc/ros2_controllers/position_controllers/doc/userdoc.html)
(simple interface, topic with one position-vector per received topic) or the [
joint trajectory controller
](https://control.ros.org/master/doc/ros2_controllers/joint_trajectory_controller/doc/userdoc.html)
(has also a topic interface, but additionally an action server; and it
interpolates optionally from a full trajectory, not only from a single point).

Have a look at the [ other examples
](https://control.ros.org/master/doc/ros2_control_demos/example_1/doc/userdoc.html)
from the demos on how to use them.


Question:
rclcpp wait for a list of service/action servers to start before proceeding further

I have a list of services and a list of actions that I need to wait for to start before I can proceed further. Is there some sort of inbuilt function in rclcpp or rclcpp::Node that I can use?

Creating a custom service and action client type is not really a viable option for me, since I would have more than 100 services + actions combined.

What I want is something like the following:

class SomeNode : public rclcpp::Node
{
public:
    SomeNode() : Node("service_and_action_check")
    {
        /* We do our initial setup */

        std::vector<std::string> serviceList = {"service1", "service2", "service3"};
        std::vector<std::string> actionList  = {"action1", "action2", "action3"};

        for (auto &elem : serviceList)
        {
            checkIfServiceServerIsRunning(elem);
        }

        for (auto &elem : actionList)
        {
            checkIfActionServerIsRunning(elem);
        }

        RCLCPP_INFO(this->get_logger(), "All services and actions have been loaded.");
    }
    .
    .
    .
};

If this is not readily available, if anyone knows of a simple way to create the functions checkIfServiceServerIsRunning and checkIfActionServerIsRunning, that would be of help too.

Thanks!

Explanation: We can use the wait_for method in services and actions. We may check its implementation, action node and client node.

$\begingroup$

Both services and actions have ` wait_for_...() ` methods, see the [ service
tutorial ](https://docs.ros.org/en/rolling/Tutorials/Beginner-Client-
Libraries/Writing-A-Simple-Cpp-Service-And-Client.html#write-the-client-node)
and rclcpp [ source code
](https://github.com/ros2/rclcpp/blob/5ffc963e1aef97928a6cc895db18d40673c655f1/rclcpp/include/rclcpp/client.hpp#L191-L198)
:

    while (!client->wait_for_service(1s)) {
        if (!rclcpp::ok()) {
            RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
            return 0;
        }
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
      }

and the [ action client tutorial
](https://docs.ros.org/en/rolling/Tutorials/Intermediate/Writing-an-Action-
Server-Client/Cpp.html#writing-an-action-client) :

    if (!this->client_ptr_->wait_for_action_server()) {
        RCLCPP_ERROR(this->get_logger(), "Action server not available after waiting");
        rclcpp::shutdown();
    }

` wait_for_action_server() ` can also take a duration, see the rclcpp_action [
source code
](https://github.com/ros2/rclcpp/blob/5ffc963e1aef97928a6cc895db18d40673c655f1/rclcpp_action/include/rclcpp_action/client.hpp#L83-L86)
.

For your application you'd have to loop over each of your services/actions and
wait untill all are available.


Question:
Why TEB controller is not available in ros2 humble?

On navigation plugin setup document , the TEB controller is mentioned, but I don't find any documentation to set up this controller in nav2 humble. And there is no humble branch in the teb_local_planner repository. So I copied the TEB parameters from foxy and launch the navigation node, but it told me the TEB controller plugin can't be found.

[controller_server-4] [FATAL] [1697706023.360686729] [controller_server]: Failed to create controller. Exception: According to the loaded plugin descriptions the class teb_local_planner::TebLocalPlannerROS with base class type nav2_core::Controller does not exist. Declared types are  dwb_core::DWBLocalPlanner nav2_mppi_controller::MPPIController nav2_regulated_pure_pursuit_controller::RegulatedPurePursuitController nav2_rotation_shim_controller::RotationShimController
So why TEB controller is not available in ros2 humble? or did I miss something? Thanks.

Explanation: The central question is to understand whether TEB controller is supported in nav2 humble. We can check post/announcement for details.

$\begingroup$

There was a [ recent post on the ROS Discourse
](https://discourse.ros.org/t/nav2-model-predictive-path-integral-mppi-
controller-now-available/30054) , about a new MPPI controller. That post
mentions:

> I would be inundated with messages regarding TEB if I did not address it
> here. While TEB is quite a fantastic piece of software, the maintainer has
> since moved on from his academic career into a position where it is not
> possible to maintain it into the future. As such, its largely unmaintained
> and represents techniques which are bordering on a decade old. This work is
> very modern and state of the art in the same vertical of techniques as TEB
> (MPC) so it meets the same need that TEB serves. With MPPI’s modern
> methodology, performance, active maintenance, and documentation, I hope you
> all will agree with me over time that this is an improvement. There are
> certain characteristics of the Elastic Band approaches that I did not like
> in a production setting that are not present in this work.

So I conclude that TEB is indeed not supported anymore.

EDIT: that thread also mentions the upcoming ROSCon 2023 presentation [ On Use
of Nav2 MPPI Controller
](https://roscon.ros.org/2023/#:%7E:text=On%20Use%20of%20Nav2%20MPPI%20Controller)
which is scheduled **today** , so you might want to watch the live feed (or
later on the recording, when it gets published).

EDIT 2: In the description of the ROSCon talk, MPPI is refered to as "the
functional successor of the TEB and DWB controllers", so it seems that MPPI is
effectively considered as the replacement for TEB:

> We introduce the Nav2 project's MPPI Local Trajectory Planner. It is the
> functional successor of the TEB and DWB controllers, providing predictive
> time-varying trajectories reminiscent of TEB while providing tunable critic
> functions similar to DWB.


Question:
How to use stereo_image_proc without camera_info topics?

I'm working with 2 csi cameras in a jetson nano with ROS2 humble and I want to do a disparity image. What I'm trying to use is stereo_image_proc disparity node, but it requires to have the camera_info topics for both of the cameras. The camera is a imx219-83 and I haven't found a driver that allows me to have a camera_info topic. Is it possible to obtain this topic ? If not, is there something that could be helpful for this situations?

Thanks!

Explanation: We may refer to Image Pipeline Tutorial in ROS2 that also  involves creating a disparity map with stereo_image_proc.

$\begingroup$

[ This tutorial ](https://jeffzzq.medium.com/ros2-image-pipeline-
tutorial-3b18903e7329) does exactly what you want, I think. They are also
creating a disparity map with stereo_image_proc.

There you will calibrate your cameras and use the opencv_cam driver to read
your devices. When reading you cameras with opencv_cam you can provide a
calibration file (.yaml) that you created with the calibration, and open_cv
cam will publish your image_raw and camera_info topic.


Question:
Joint Trajectory Controller with velocity command interface has non-zero velocity after finshed trajectory

I want to control a manipulator with the Joint Trajectory Controller by using the velocity command interface. I am planning a trajectory with with MoveIt MotionPlanningof rviz. I am using ros2 humble.

I've tested several setups but with all of them I have the same problem: When the Joint Trajectory Controller reports "Goal reached, success!", the velocities aren't set to zero. I tried to play with with the parameters (increasing and decreasing stopped_velocity_tolerance or goal_time, changing the gains, adding and removing ff_velocity_scale) which sometimes leads to a smaller final velocity but never to completely stopped motion.

A simple setup to reproduce this issue is by launching ros2 launch moveit2_tutorials demo.launch.py from (moveit2_tutorials)[https://github.com/ros-planning/moveit2_tutorials] but with changing from position to velocity interface in the panda_moveit_config. I changed

Settings for panda_arm_controller in ros2_controllers.yaml to:
panda_arm_controller:
  ros__parameters:
    command_interfaces:
      - velocity
    state_interfaces:
      - position
      - velocity
    joints:
      - panda_joint1
      - panda_joint2
      - panda_joint3
      - panda_joint4
      - panda_joint5
      - panda_joint6
      - panda_joint7
    gains:
      panda_joint1:
        p: 10.0
        i: 1.0
        d: 1.0
        i_clamp: 1.0
        ff_velocity_scale: 1.0
      panda_joint2:
        p: 10.0
        i: 1.0
        d: 1.0
        i_clamp: 1.0
        ff_velocity_scale: 1.0
      panda_joint3:
        p: 10.0
        i: 1.0
        d: 1.0
        i_clamp: 1.0
        ff_velocity_scale: 1.0
      panda_joint4:
        p: 10.0
        i: 1.0
        d: 1.0
        i_clamp: 1.0
        ff_velocity_scale: 1.0
      panda_joint5:
        p: 10.0
        i: 1.0
        d: 1.0
        i_clamp: 1.0
        ff_velocity_scale: 1.0
      panda_joint6:
        p: 10.0
        i: 1.0
        d: 1.0
        i_clamp: 1.0
        ff_velocity_scale: 1.0
      panda_joint7:
        p: 10.0
        i: 1.0
        d: 1.0
        i_clamp: 1.0
        ff_velocity_scale: 1.0
Setting command_interface from position to velocity in panda.ros2_control.xacro:
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:macro name="panda_ros2_control" params="name initial_positions_file ros2_control_hardware_type">
        <xacro:property name="initial_positions" value="${xacro.load_yaml(initial_positions_file)['initial_positions']}"/>

        <ros2_control name="${name}" type="system">
        <hardware>
            <xacro:if value="${ros2_control_hardware_type == 'mock_components'}">
                    <plugin>mock_components/GenericSystem</plugin>
                    <param name="calculate_dynamics">true</param>
                </xacro:if>
                <xacro:if value="${ros2_control_hardware_type == 'isaac'}">
                <plugin>topic_based_ros2_control/TopicBasedSystem</plugin>
                <param name="joint_commands_topic">/isaac_joint_commands</param>
                <param name="joint_states_topic">/isaac_joint_states</param>
            </xacro:if>
        </hardware>
        <joint name="panda_joint1">
            <command_interface name="velocity"/>
            <state_interface name="position">
              <param name="initial_value">${initial_positions['panda_joint1']}</param>
                </state_interface>
                <state_interface name="velocity"/>
            </joint>
            <joint name="panda_joint2">
                <command_interface name="velocity"/>
                <state_interface name="position">
                  <param name="initial_value">${initial_positions['panda_joint2']}</param>
            </state_interface>
            <state_interface name="velocity"/>
        </joint>
        <joint name="panda_joint3">
            <command_interface name="velocity"/>
            <state_interface name="position">
              <param name="initial_value">${initial_positions['panda_joint3']}</param>
                </state_interface>
                <state_interface name="velocity"/>
            </joint>
            <joint name="panda_joint4">
                <command_interface name="velocity"/>
                <state_interface name="position">
                  <param name="initial_value">${initial_positions['panda_joint4']}</param>
            </state_interface>
            <state_interface name="velocity"/>
        </joint>
        <joint name="panda_joint5">
            <command_interface name="velocity"/>
            <state_interface name="position">
              <param name="initial_value">${initial_positions['panda_joint5']}</param>
                </state_interface>
                <state_interface name="velocity"/>
            </joint>
            <joint name="panda_joint6">
                <command_interface name="velocity"/>
                <state_interface name="position">
                  <param name="initial_value">${initial_positions['panda_joint6']}</param>
            </state_interface>
            <state_interface name="velocity"/>
        </joint>
        <joint name="panda_joint7">
            <command_interface name="velocity"/>
            <state_interface name="position">
              <param name="initial_value">${initial_positions['panda_joint7']}</param>
                </state_interface>
                <state_interface name="velocity"/>
            </joint>
        </ros2_control>
    </xacro:macro>
</robot>
Now you can run ros2 launch moveit2_tutorials demo.launch.py, open a second terminal and run ros2 topic echo /joint_states. Plan an arbitrary trajectory by using rviz and hit Plan & Execute in the MotionPlanning panel of rviz. Then you should see a motion being executed and the terminal should report:

[ros2_control_node-5] [INFO] [1697458106.110702550] [panda_arm_controller]: Goal reached, success!
[move_group-4] [INFO] [1697458106.122919526] [moveit.simple_controller_manager.follow_joint_trajectory_controller_handle]: Controller 'panda_arm_controller' successfully finished
[move_group-4] [INFO] [1697458106.151076866] [moveit_ros.trajectory_execution_manager]: Completed trajectory execution with status SUCCEEDED ...
[move_group-4] [INFO] [1697458106.151414260] [moveit_move_group_default_capabilities.move_action_capability]: Solution was found and executed.
[rviz2-1] [INFO] [1697458106.151859534] [move_group_interface]: Plan and Execute request complete!
In parallel you can check the logs of ros2 topic echo /joint_states which should report non-zero velocities even after the trajectory is successfully executed. Therefore the arm keeps moving (slowly but steady) and you should see the positions constantly changing.

Is this the intended behavior of the Joint Trajectory Controller? Or do I just have a bad parameter setup? Any help or hint on what the problem could be would be highly appreciated!

Explanation: This is related to velocity or effort command interface. We can check related discussions.

$\begingroup$

Which ROS distro are you using? This is a well-known "feature"/bug and was [
fixed for rolling/iron packages ](https://github.com/ros-
controls/ros2_controllers/pull/558) . I plan to backport this fix to humble,
but this might still take some time to ensure not breaking existing setups.


Question:
How to publish pose of the lidar/camera/(or any dynamic/static model) in gazebo fortress?

I am trying publish the pose of the camera and view it in rviz2. I am using ros2 Humble and gazebo fortress. I can see the image using the image topic but i am not able to visualize the topic in the gazebo as well. Here is my sdf file.

<?xml version="1.0" ?>
<sdf version="1.6">
  <world name="test">
    <plugin
      filename="ignition-gazebo-physics-system"
      name="gz::sim::systems::Physics">
    </plugin>
    <plugin
      filename="ignition-gazebo-sensors-system"
      name="gz::sim::systems::Sensors">
      <render_engine>ogre2</render_engine>
    </plugin>
    <plugin
      filename="ignition-gazebo-user-commands-system"
      name="gz::sim::systems::UserCommands">
    </plugin>
    <plugin
      filename="ignition-gazebo-scene-broadcaster-system"
      name="gz::sim::systems::SceneBroadcaster">
    </plugin>
    <light type="directional" name="sun">
      <cast_shadows>true</cast_shadows>
      <pose>0 0 10 0 0 0</pose>
      <diffuse>0.8 0.8 0.8 1</diffuse>
      <specular>0.2 0.2 0.2 1</specular>
      <attenuation>
        <range>1000</range>
        <constant>0.9</constant>
        <linear>0.01</linear>
        <quadratic>0.001</quadratic>
      </attenuation>
      <direction>-0.5 0.1 -0.9</direction>
    </light>

    <model name="ground_plane">
      <static>true</static>
      <link name="link">
        <collision name="collision">
          <geometry>
            <plane>
              <normal>0.0 0.0 1</normal>
              <size>100 100</size>
            </plane>
          </geometry>
        </collision>
        <visual name="visual">
          <geometry>
            <plane>
              <normal>0.0 0.0 1</normal>
              <size>100 100</size>
            </plane>
          </geometry>
          <material>
            <ambient>0.8 0.8 0.8 1</ambient>
            <diffuse>0.8 0.8 0.8 1</diffuse>
            <specular>0.8 0.8 0.8 1</specular>
          </material>
        </visual>
      </link>
    </model>

    <model name="box">
      <pose>5.0 0 0.7 0 0 0</pose>
      <link name="box_link">
        <inertial>
          <inertia>
            <ixx>1</ixx>
            <ixy>0</ixy>
            <ixz>0</ixz>
            <iyy>1</iyy>
            <iyz>0</iyz>
            <izz>1</izz>
          </inertia>
          <mass>1.0</mass>
        </inertial>
        <collision name="box_collision">
          <geometry>
            <box>
              <size>1 1 1</size>
            </box>
          </geometry>
        </collision>

        <visual name="box_visual">
          <geometry>
            <box>
              <size>1 1 1</size>
            </box>
          </geometry>
          <material>
            <ambient>0.3 0.3 0.3 1</ambient>
            <diffuse>0.3 0.3 0.3 1</diffuse>
            <specular>0.3 0.5 0.3 1</specular>
          </material>
        </visual>
      </link>
    </model>

    <model name="model_with_camera">
      <static>true</static>
      <pose>4 -6 2 0 0 1.57</pose>
      <link name="link">
        <pose>0.05 0.05 0.05 0 0 0</pose>
        <visual name="visual">
          <geometry>
            <box>
              <size>0.1 0.1 0.1</size>
            </box>
          </geometry>
        </visual>
        <sensor name="camera" type="camera">
          <camera>
            <horizontal_fov>1.047</horizontal_fov>
            <image>
              <width>640</width>
              <height>480</height>
            </image>
            <clip>
              <near>0.1</near>
              <far>100</far>
            </clip>
          </camera>
          <always_on>1</always_on>
          <update_rate>30</update_rate>
          <visualize>true</visualize>
          <topic>camera</topic>
        </sensor>
      </link>
    </model>

    <model name="lidar">
      <pose>4.05 -6 2 0 0 1.57</pose>
      <link name="link">
        <pose>0.05 0.05 0.05 0 0 0</pose>
        <inertial>
          <mass>0.1</mass>
          <inertia>
            <ixx>0.000166667</ixx>
            <iyy>0.000166667</iyy>
            <izz>0.000166667</izz>
          </inertia>
        </inertial>
        <collision name="collision">
          <geometry>
            <box>
              <size>0.1 0.1 0.1</size>
            </box>
          </geometry>
        </collision>
        <visual name="visual">
          <geometry>
            <box>
              <size>0.1 0.1 0.1</size>
            </box>
          </geometry>
        </visual>

        <sensor name='gpu_lidar' type='gpu_lidar'>
          <topic>lidar</topic>
          <update_rate>10</update_rate>
          <lidar>
            <scan>
              <horizontal>
                <samples>1024</samples>
                <resolution>1</resolution>
                <min_angle>-1.396263</min_angle>
                <max_angle>1.396263</max_angle>
              </horizontal>
              <vertical>
                <samples>64</samples>
                <resolution>1</resolution>
                <min_angle>-0.261799</min_angle>
                <max_angle>0.261799</max_angle>
              </vertical>
            </scan>
            <range>
              <min>0.08</min>
              <max>30.0</max>
              <resolution>0.01</resolution>
            </range>
          </lidar>
          <alwaysOn>1</alwaysOn>
          <visualize>true</visualize>
        </sensor>

        <plugin
            filename="ignition-gazebo-pose-publisher-system"
            name="gz::sim::systems::PosePublisher">
            <publish_link_pose>true</publish_link_pose>
            <publish_sensor_pose>true</publish_sensor_pose>
            <use_pose_vector_msg>true</use_pose_vector_msg>
            <static_publisher>true</static_publisher>
        </plugin>
      </link>
      <static>true</static>
    </model>
  </world>
</sdf>
I tried to publish the pose of the lidar using pose-publisher-system as well. Thank you.

Explanation: We need to check the usage of pose plugin, e.g., with examples

$\begingroup$

A Gazebo Sim system plugin can only be attached to a ` <world> ` , a ` <model>
` or a ` <sensor> ` , not to a ` <link> ` . You should be getting an error
message for this in the log output, I think even without verbose output
enabled. In any case: for testing purposes it is advisable to enable verbose
output ( ` -v 4 ` ), e.g.:

    ign gazebo -v 4 world.sdf

All standard Gazebo Fortress system plugins can be found in the [ GitHub
repository ](https://github.com/gazebosim/gz-sim/tree/ign-gazebo6/src/systems)
. See the other branches of that repository for the other Gazebo Sim versions.

Each plugin has usage documentation in its header file. For the `
PosePublisher ` system see [ this part of the header file
](https://github.com/gazebosim/gz-
sim/blob/14b0f3b42da811cdd8fb24e983c2b2598a855c91/src/systems/pose_publisher/PosePublisher.hh#L35-L66)
.

I haven't used that plugin yet, but given following documentation I conclude
that you just have to add the plugin to the ` <model> ` in order to get all
pose information published:

> Attach to an entity to publish the transform of its child entities in the
> form of gz::msgs::Pose messages, or a single gz::msgs::Pose_V message if
> "use_pose_vector_msg" is true.

The GitHub repository also holds [ example worlds
](https://github.com/gazebosim/gz-sim/tree/ign-gazebo6/examples/worlds) that
show the use of each plugin. [ Here ](https://github.com/gazebosim/gz-
sim/blob/ign-gazebo6/examples/worlds/pose_publisher.sdf) is the one for the
pose publisher.


Question:
How to get sensor data over a topic with webots_ros2 plugin?

I've installed webots 2023b and after I saw that a world with and inverted pendulum has been already shipped in the default installation directory, I decided to use that world for my project.

Basically I followed this tutorial and this tutorial to be able to publish sensor data directly from the urdf file itself. That means, that I create this file:

<?xml version="1.0" ?>
<robot name="Inverted Pendulum">
    <webots>
        <device reference="hip" type="PositionSensor">
            <ros>
                <topicName>/hip</topicName>
                <alwaysOn>true</alwaysOn>
            </ros>
        </device>
        <device reference="horizontal position sensor" type="PositionSensor">
            <ros>
                <topicName>/horizontal_position</topicName>
                <alwaysOn>true</alwaysOn>
            </ros>
        </device>
        <plugin type="inverted_pendulum.device_driver.InvertedPendulum"/>
    </webots>
</robot>
but, even if, everything starts correctly (no errors or warnings in webots), doing a:

    $ros2 topic list
does not show any topic with the name /hip or /horizontal_position. It hangs forever waiting for data to be published.

The simulator is not paused, since I created a driver, which moves the cart forth and back.

Any idea?

The code for the world is the same. I changed only the name. But I add it here anyway, just in case.

#VRML_SIM R2023b utf8

EXTERNPROTO "https://raw.githubusercontent.com/cyberbotics/webots/R2023b/projects/objects/backgrounds/protos/TexturedBackground.proto"
EXTERNPROTO "https://raw.githubusercontent.com/cyberbotics/webots/R2023b/projects/objects/floors/protos/Floor.proto"

WorldInfo {
  info [
    "An example of hot to solve the Inverted Pendulum problem using a PID controller"
  ]
  title "Inverted Pendulum"
  basicTimeStep 16
  contactProperties [
    ContactProperties {
      material1 "robot_basis"
      material2 "floor"
      coulombFriction [
        0.2
      ]
    }
  ]
}
Viewpoint {
  orientation -0.0996069518072968 -0.03685053329082472 0.9943442529364971 3.666446119327704
  position 13.193129047100818 10.690115274872808 4.2889817843979205
  follow "robot:solid"
}
TexturedBackground {
}
Floor {
  size 1000 2
  appearance PBRAppearance {
    baseColorMap ImageTexture {
      url [
        "https://raw.githubusercontent.com/cyberbotics/webots/R2023b/projects/default/worlds/textures/checkered_marble.jpg"
      ]
    }
    roughness 1
    metalness 0
  }
}
Robot {
  rotation 0 0 1 3.14159
  children [
    SliderJoint {
      jointParameters JointParameters {
        axis 1 0 0
        dampingConstant 1.5
      }
      device [
        LinearMotor {
          name "horizontal_motor"
          maxForce 40
        }
        PositionSensor {
          name "horizontal position sensor"
        }
      ]
      endPoint Solid {
        translation 0 0 0.06
        children [
          DEF ROBOT_SHAPE Shape {
            appearance PBRAppearance {
              baseColor 0.2443427176317998 0.704051270313573 0.1756923781185626
              roughness 1
              metalness 0
            }
            geometry Box {
              size 0.3 0.1 0.1
            }
          }
          DEF HIP HingeJoint {
            jointParameters HingeJointParameters {
              position 0.000161402
              axis 0 1 0
              anchor 0 0 0.03
            }
            device [
              PositionSensor {
                name "hip"
              }
            ]
            endPoint DEF THIGH_BB Solid {
              translation 0 -0.061 0.33000000000000007
              rotation 0 1 0 0
              children [
                Shape {
                  appearance PBRAppearance {
                    baseColor 0.8496833752956435 0.07072556649118791 0.09393453879606317
                    roughness 1
                    metalness 0
                  }
                  geometry DEF THIGH_BOX Box {
                    size 0.05 0.02 0.6
                  }
                }
              ]
              boundingObject USE THIGH_BOX
              physics Physics {
                density -1
                mass 0.05
                centerOfMass [
                  0 0.061 -0.27
                ]
              }
            }
          }
          PointLight {
            attenuation 0 0 1
            intensity 5
            location 0 0 2
          }
        ]
        contactMaterial "robot_basis"
        boundingObject USE ROBOT_SHAPE
        physics Physics {
          density -1
          mass 1
        }
      }
    }
  ]
  name "Inverted_Pendulum"
  boundingObject Box {
    size 200 0.1 0.01
  }
  physics Physics {
    density -1
    mass 30
  }
  controller "<extern>"
}

Explanation: This is related to ros2_control. We may check the ros2_control interface for webots_ros2.

$\begingroup$

There is no position sensor ROS plugin in ` webots_ros2 ` .

There are two ways to get joint position data published:

  * Use [ ` ros2_control ` ](https://control.ros.org/master/index.html) . There is a ` ros2_control ` interface for ` webots_ros2 ` called [ ` webots_ros2_control ` ](https://github.com/cyberbotics/webots_ros2/tree/master/webots_ros2_control) (see usage example [ here ](https://github.com/cyberbotics/webots_ros2/blob/b0361c09c13e070be76d85aa89d9d0794b6d2a0b/webots_ros2_turtlebot/resource/turtlebot_webots.urdf#L33%5D) ). In your case, you will need to spawn [ ` joint_state_broadcaster ` ](https://control.ros.org/master/doc/ros2_controllers/joint_state_broadcaster/doc/userdoc.html) which publishes joints state messages. This is generally a recommended way to interact with joints in ROS as you can achieve hard control loops, much better performance, and simpler sim2real transfer.
  * Create a custom ` webots_ros2 ` plugin (see the [ tutorial ](https://docs.ros.org/en/humble/Tutorials/Advanced/Simulators/Webots/Setting-Up-Simulation-Webots-Basic.html) ). You can use it to create a joint state publisher and publish joints state messages.


Question:
ros2 parameter setting

I would like to follow a simple take off and land example without any launch files or yaml files on ros2 crazyswarm (Physical Experiments part). What could be the reason for the following output, thanks.

ntukenmez3@ae-icps-407120:~/Documents/ros2_ws$ ros2 param set crazyflie_server cf231.params.commander.enHighLevel 1
Setting parameter failed

Explanation: The cause may be the incorrect setup of crazyflie. We may check the example of crazyflie.yml.

$\begingroup$

Be sure you set up correctly the ` crazyflies.yaml ` file: [ link
](https://imrclab.github.io/crazyswarm2/usage.html#crazyflies-yaml)


Question:
How to put ArUco markers in Gazebo Classic

The title says it all. I would like to test my robot's ArUco recognition and processing abilities by putting some markers around environments in classic Gazebo.

All the tutorials I see online seem to be for older versions of Gazebo and (frankly) use some very elaborate tricks.

What is the canonical way of adding a marker to Gazebo?

EDIT: My version of Gazebo is 11.10.2, by "older versions of Gazebo" I mean older versions of Gazebo classic specifically. Sorry for any confusion.

Explanation: We can check some implementation examples about how it works.

$\begingroup$

[ This forum post ](https://answers.gazebosim.org//question/27574/is-it-
possible-to-create-an-aruco-marker-and-add-it-to-gazebo11/) and [ this blog
post ](https://nlamprian.me/blog/software/ros/2020/01/27/visual-servoing-in-
gazebo/) and corresponding [ example model
](https://github.com/nlamprian/grobot/tree/master/grobot_gazebo/models/aruco_marker)
are pretty helpful.

This is just a simple [ model
](https://github.com/nlamprian/grobot/blob/78fd627990f743997138015d14e9059079e3044f/grobot_gazebo/models/aruco_marker/model.sdf#L3)
defining a link which has a [ front visual
](https://github.com/nlamprian/grobot/blob/78fd627990f743997138015d14e9059079e3044f/grobot_gazebo/models/aruco_marker/model.sdf#L17-L31)
and a [ back visual
](https://github.com/nlamprian/grobot/blob/78fd627990f743997138015d14e9059079e3044f/grobot_gazebo/models/aruco_marker/model.sdf#L33-L40)
. The front visual loads the aruco marker throug a [ material script
](https://github.com/nlamprian/grobot/blob/78fd627990f743997138015d14e9059079e3044f/grobot_gazebo/models/aruco_marker/model.sdf#L25-L29)
.

There is nothing "very elaborately tricky" about this, this is just how
textures are done in Gazebo Classic. The material script and the marker image
are [ here
](https://github.com/nlamprian/grobot/tree/master/grobot_gazebo/models/aruco_marker/materials)
; this should be self-explanatory.

Given you mention "older versions of Gazebo": be aware that there is 'Gazebo
Classic' which typically has version _numers_ and is currently at version 11,
and there is 'Gazebo Sim' (i.e. 'New Gazebo') which gets version _names_ ,
e.g. Fortress, Garden, Harmonic. Gazebo Sim used to be called 'Ignition'. This
was changed to 'Gazebo Sim' due to some trademark issues wrt 'ignition'.

The material scripts work for Gazebo _Classic_ , not for Gazebo _Sim_ . If you
need a solution for Gazebo Sim, then [ this
](https://www.youtube.com/watch?v=A3fJwTL2O4g) looks promising (I did not test
it, but it seems to generate a ` dae ` model and load it as a mesh, which is
indeed a possible way to load textures in Gazebo Sim).


Question:
Cannot locate rosdep definition, error on micro-ROS

I'm trying to set up micro-ROS on Ubuntu 20.04 using this website, and connect ESP32 to ROS 2. However, when executing the command ros2 run micro_ros_setup create_firmware_ws.sh freertos esp32, I get the following error:

ERROR: the following packages/stacks could not have their rosdep keys resolved
to system dependencies:
rclc_parameter: Cannot locate rosdep definition for [osrf_testing_tools_cpp]
rmw: Cannot locate rosdep definition for [osrf_testing_tools_cpp]
rmw_implementation: Cannot locate rosdep definition for [rcpputils]
rosidl_typesupport_c: Cannot locate rosdep definition for [mimick_vendor]
rosidl_default_runtime: Cannot locate rosdep definition for [rosidl_typesupport_introspection_cpp]
rcl_logging_noop: Cannot locate rosdep definition for [launch_testing]
rosidl_typesupport_microxrcedds_c_tests: Cannot locate rosdep definition for [rosidl_typesupport_introspection_c]
tracetools_launch: Cannot locate rosdep definition for [launch_ros]
rcutils: Cannot locate rosdep definition for [osrf_testing_tools_cpp]
rcl_action: Cannot locate rosdep definition for [osrf_testing_tools_cpp]
libyaml_vendor: Cannot locate rosdep definition for [rcpputils]
rcl_lifecycle: Cannot locate rosdep definition for [osrf_testing_tools_cpp]
tracetools_test: Cannot locate rosdep definition for [launch_ros]
test_rmw_implementation: Cannot locate rosdep definition for [rmw_dds_common]
rclc_lifecycle: Cannot locate rosdep definition for [osrf_testing_tools_cpp]
rosidl_typesupport_cpp: Cannot locate rosdep definition for [rcpputils]
rcl: Cannot locate rosdep definition for [rcpputils]
ros2trace: Cannot locate rosdep definition for [ros2cli]
rclc: Cannot locate rosdep definition for [osrf_testing_tools_cpp]
Is there any solution?

Incidentally, I implemented the following solution suggested by ChatGPT, but it didn't improve the situation.

Update ROS 2 dependencies. rosdep update
Install System Packages, which ROS2 packages or stacks depend on. rosdep install --from-paths /path/to/your/ros2/workspace --ignore-src --rosdistro <your_ros_distro>
Rebuild the ROS 2 workspace. colcon build

Explanation: This looks like using galactic. We may check recent releases to see the supported distributions.

$\begingroup$

Since you mention that you are using ` Ubuntu 20.04 ` , you can not use the
tutorial. It is written for ` Ubuntu 22.04 ` ( [
https://micro.ros.org/docs/tutorials/core/first_application_rtos/freertos/#:~:text=Hawksbill%20on%20your-,Ubuntu%2022.04,-LTS%20computer.%20To
](https://micro.ros.org/docs/tutorials/core/first_application_rtos/freertos/#:%7E:text=Hawksbill%20on%20your-,Ubuntu%2022.04,-LTS%20computer.%20To)
)

I assume you are trying to use **galactic** , which is not supported any more
( [ https://docs.ros.org/en/rolling/Releases.html
](https://docs.ros.org/en/rolling/Releases.html) )


Question:
Intel RealSense with ROS 2

I am just getting started with Intel Real Sense integration with ROS2. When trying to install Intel real sense packages in ROS 2 Humble, the official documentation says the supported kernel version of this package is only for 5.4 or less. On the contrary, by default, the kernel version of ROS2 humble in Ubuntu 22 is 6.

Please give some input on whether ROS2 Humble supports real-sense integration.

Explanation: We may need to configure your Ubuntu repositories in order to install these packages. We can check the official documents for details.

$\begingroup$

Welcome to Robotics Stack Exchange!

In short, the Intel RealSense camera works with ROS 2. You are looking at the
documentation of the ` librealsense ` , which may not be updated accordingly.
Anyways, I strongly suggest installing the prebuilt package using ` apt ` .
Below is an example:

    sudo apt install ros-<ROS_DISTRO>-librealsense2*
    sudo apt install ros-<ROS_DISTRO>-realsense2-*

Please note that you may need to configure your Ubuntu repositories in order
to install these packages. So, please look at [ the official documentation
](https://github.com/IntelRealSense/realsense-ros#--installation) .


Question:
Gazebo Garden Detachable Joint with moving object causing massive velocity errors

I am trying to simulate the control of a caught heavy object in gazebo garden. To do so I have a plugin that creates a detachable fixed joint between the object and the end-effector of my robot once collision occurs, the issue is that when the joint is created the velocity of the object dramatically increases, while also changing direction. I originally believed that is was due to incorrect inertia parameters, however most other tests / collisions work as expected so I assume something is going wrong with the joint creation.

A synopsis of how my system works is that there is a collision sensor on the end effector, which triggers with contact with a specific object, it sends a boolean value to a topic that this plugin subscribes to, which then creates the joint between the 2 links, so long as the plugin had first been enabled.

this plugin takes heavy inspiration from the detachable joint system inside the gz_sim repo

gazebo Versions:

sim: 7.5.0
plugin: 2.0.1
transport 12.2.0
#include <detachable_joint_creator.hpp>

#include <gz/plugin/Register.hh>
#include <gz/transport/Node.hh>
#include <functional>
#include <gz/sim/components/DetachableJoint.hh>
#include <gz/sim/Model.hh>
#include <gz/sim/Joint.hh>
#include <gz/sim/Link.hh>
using namespace monke_plugins;

JointCreator::JointCreator():
dataPtr(new JointCreatorPrivate)
{

}
JointCreator::~JointCreator(){

}
void JointCreator::Configure(const gz::sim::Entity &_entity,
    const std::shared_ptr<const sdf::Element> & _sdf,
    gz::sim::EntityComponentManager &_ecm,
    gz::sim::EventManager &/*_eventMgr*/
){

    // Initialise the Plugin via sdf elements

    gzmsg << "loading JointCreator plugin\n";
    if(_sdf->HasElement("parent")){

        this->dataPtr->end_effector_link_name = _sdf->Get<std::string>("parent");
    }
    else{
        gzerr << "[parent] link name not specified in sdf \n";
        return;
    }

    gz::sim::Model model(_entity);
    this->dataPtr->end_effector_entity = model.LinkByName(_ecm, this->dataPtr->end_effector_link_name);
    if (this->dataPtr->end_effector_entity == gz::sim::kNullEntity)
        {
        gzerr << "Could not find link named "<< this->dataPtr->end_effector_link_name << std::endl;
        return;
        }

    if(_sdf->HasElement("contact_sensor_topic")){
        this->dataPtr->contact_sensor_topic = _sdf->Get<std::string>("contact_sensor_topic");
        std::function<void(const gz::msgs::Contacts &)> callback = [this](gz::msgs::Contacts msg){this->ContactSensorCallback(msg);};
        if(!this->dataPtr->transport_node->Subscribe<gz::msgs::Contacts>(this->dataPtr->contact_sensor_topic,callback)){
            gzerr << "Failed to subscribe to topic [" << this->dataPtr->contact_sensor_topic << "] \n";
            return;
        }
        //? idk if advertising a subscription works
        this->dataPtr->transport_node->Advertise<gz::msgs::Contacts>(this->dataPtr->contact_sensor_topic);

    }
    else{
        gzerr << "detachable_joint plugin has no SDF Element contact_sensor_topic";
        return;
    }

    if(_sdf->HasElement("command_topic")){
        this->dataPtr->command_topic = _sdf->Get<std::string>("command_topic");
        std::function<void(const gz::msgs::Boolean &)> callback = [this](gz::msgs::Boolean msg){this->CommandCallback(msg);};
        if(!this->dataPtr->transport_node->Subscribe<gz::msgs::Boolean>(this->dataPtr->command_topic,callback)){
            gzerr << "Failed to subscribe to topic [" << this->dataPtr->command_topic << "] \n";
            return;
        }
        //? idk if advertising a subscription works
        this->dataPtr->transport_node->Advertise<gz::msgs::Boolean>(this->dataPtr->command_topic);

    }
    else{
        gzerr << "detachable_joint plugin has no SDF Element command_topic";
        return;
    }

    if(_sdf->HasElement("triggered_topic")){
        this->dataPtr->triggered_topic = _sdf->Get<std::string>("triggered_topic");

         this->dataPtr->publisher = std::make_unique<gz::transport::Node::Publisher>(this->dataPtr->transport_node->Advertise<gz::msgs::Boolean>(this->dataPtr->triggered_topic));

    }
    else{
        gzerr << "detachable_joint plugin has no SDF Element triggered_topic";
        return;
    }

}

void JointCreator::PostUpdate(const gz::sim::UpdateInfo &_info,
const gz::sim::EntityComponentManager &_ecm){

    if(_info.paused){return;} //if sim is paused.

    // gzmsg << "JointCreator::PostUpdate - " << _info.simTime.count() << std::endl;

}

void JointCreator::PreUpdate(const gz::sim::UpdateInfo &_info,
gz::sim::EntityComponentManager &_ecm){
    if(_info.paused){return;} //if sim is paused.

    auto Contact = [this](){return(this->dataPtr->contacted_entity != gz::sim::kNullEntity);};

    if(this->dataPtr->PluginActive && !this->dataPtr->JointCreated && Contact()){ //! CREATE JOINT
        // if the joint is active, it has not been created, and contact is made, then create the joint
        this->dataPtr->joint = _ecm.CreateEntity();
        auto parentLink = _ecm.ParentEntity(this->dataPtr->contacted_entity); //create a new link as the parent entity of the obejct we're trying to grab
        _ecm.CreateComponent(
            this->dataPtr->joint,
            gz::sim::components::DetachableJoint({this->dataPtr->end_effector_entity,parentLink,"fixed"})
            );
        gzdbg << "created detachable joint between end effector & [" << this->dataPtr->contacted_entity<< "] @ " << _info.simTime.count() <<"\n";
        gz::msgs::Boolean msg;
        msg.set_data(true);
        this->dataPtr->publisher->Publish(msg);

        this->dataPtr->JointCreated = true;

    }
    if(!this->dataPtr->PluginActive && this->dataPtr->JointCreated){//! DESTROY JOINT
        // if the joint is not active and the joint has been created, then destroy the joint.
        _ecm.RequestRemoveEntity(this->dataPtr->joint,true);
        this->dataPtr->joint = gz::sim::kNullEntity;

        gzdbg << "deleted detachable joint between end effector & ["<< this->dataPtr->child_entity << "] @ " << _info.simTime.count() <<"\n";
        gz::msgs::Boolean msg;
        msg.set_data(false);
        this->dataPtr->publisher->Publish(msg);
        this->dataPtr->JointCreated = false;
    }

}

void JointCreator::CommandCallback(const gz::msgs::Boolean & _msg){
    gzmsg << "JointCreator received command msg [" << _msg.data() << "]\n";
    this->dataPtr->PluginActive = _msg.data();
}

void JointCreator::ContactSensorCallback(const gz::msgs::Contacts & _msg){
    if(_msg.contact_size()){
        gzmsg << "JointCreator received contact msg with object: [" << _msg.contact(0).collision2().id() << "]\n";
        auto contact = _msg.contact(0);
        this->dataPtr->contacted_entity = contact.collision2().id();

    }
    else{
        this->dataPtr->contacted_entity = gz::sim::kNullEntity;
    }
}

GZ_ADD_PLUGIN(
    monke_plugins::JointCreator,
    gz::sim::System,
    monke_plugins::JointCreator::ISystemPreUpdate,
    // sample_system::JointCreator::ISystemUpdate,
    monke_plugins::JointCreator::ISystemPostUpdate,
    monke_plugins::JointCreator::ISystemConfigure
)
// GZ_ADD_PLUGIN_ALIAS(sample_system::JointCreator,"gz::sim:systems::JointCreator")
```

Explanation: The problem is related to the model collision. We may check details about collion between detached models.

$\begingroup$

There's a [ remark in the tutorial ](https://github.com/gazebosim/gz-
sim/blob/gz-sim8/tutorials/detachable_joints.md) that models should not be
colliding when the detachable joint is made. See also [ this discussion
](https://github.com/gazebosim/gz-sim/pull/1687#pullrequestreview-1440781144)
in the pull request.

So I think the behavior you experience is due to this.

An alternative, instead of checking for _contact_ , you could check for
_distance_ and create the joint when the object is close enough.

Or, in a similar previous question I suggested [ to use a PerformerDetector
](https://robotics.stackexchange.com/questions/25095/gazebo-garden-how-to-get-
colliding-entities-with-gpu-lidar-sensor-ray/25099#25099) . This reports when
an object enters a specific volume. I have not tried this yet, but the idea is
that you could place a small detection volume at the center of your gripper
and get notified if (and which) object overlaps with that region. And then you
can create the joint with that object.

Note that there is a remark to that answer that the "PerformerDetector uses
axis aligned boxes". Not sure what that means and why it would be an issue.


Question:
Point cloud in gazebo environment

I am working on a project whose main objective is to check the sensors that can perceive the environment and implement those in gazebo environment. so i am trying to implement lidar sensor and generate point cloud of the outdoor environment. Can anyone guide me how to generate a point cloud of an outdoor environment in Ignition Gazebo Fortress?

Explanation: The user wants to take a ros2 PointCloud2 message and write it to a .pcd file. We may check instructions to do this.

$\begingroup$

So you want to take a ros2 PointCloud2 message and write it to a .pcd file.

There is a existing ros1/ros2 package called ` pcl_ros ` . The src code for
both is in this [ github repo ](https://github.com/ros-
perception/perception_pcl) , but I don't know the current status of the port
to ros2. This package has a ros node named ` pointcloud_to_pcd ` that writes
PointCloud2 messages into .pcd files.


Question:
Use sim time with Moveit

I am having a problem trying to use Moveit2 in simulation, I created the Moveit config package for my robot arm using the setup assistant, but the generated move_group.launcy.py file looks like this:

from moveit_configs_utils import MoveItConfigsBuilder
from moveit_configs_utils.launches import generate_move_group_launch

def generate_launch_description():
    moveit_config = MoveItConfigsBuilder("ur", package_name="flower_catcher_moveit_config").to_moveit_configs()
    return generate_move_group_launch(moveit_config)
The problem with this format is that there is no way for me to set the use_sim_time parameter to true, and that causes the path execution to fail with this error:

[move_group-7] [INFO] [1696192877.744131744] [moveit_ros.current_state_monitor]: Didn't receive robot state (joint angles) with recent timestamp within 1.000000 seconds. Requested time 1696192876.744054, but latest received state has time 148.003000.
I kind of solved the problem by setting the parameter afterward with the command

ros2 param set /move_group use_sim_time true
However, I want to know if there is a way to set this parameter in the launch file.

Thanks!

Explanation: The user wants to set use_sim_time to be true in the config. We may check issues/discussions that also involve using this parameter.

$\begingroup$

Unfortunately, there is no clean way to pass it through launch file, while
using ` moveit_configs_utils.launches ` . This was raised previously in an [
issue ](https://github.com/ros-
planning/moveit2/issues/1810#issuecomment-1353538795) and ` use_sim_time `
technically supposed to be added [ here ](https://github.com/ros-
planning/moveit2/blob/5dd0d5e63c9dae08976656cb1c8473ca7a34c058/moveit_configs_utils/moveit_configs_utils/launches.py#L225)
in the source code. That said, here is an engineered solution around this:

    from moveit_configs_utils import MoveItConfigsBuilder
    from moveit_configs_utils.launches import *
    def generate_move_group_launch(moveit_config):
        ld = LaunchDescription()
        ld.add_action(DeclareBooleanLaunchArg("debug", default_value=False))
        ld.add_action(
            DeclareBooleanLaunchArg("allow_trajectory_execution", default_value=True)
        )
        ld.add_action(
            DeclareBooleanLaunchArg("publish_monitored_planning_scene", default_value=True)
        )
        # load non-default MoveGroup capabilities (space separated)
        ld.add_action(DeclareLaunchArgument("capabilities", default_value=""))
        # inhibit these default MoveGroup capabilities (space separated)
        ld.add_action(DeclareLaunchArgument("disable_capabilities", default_value=""))
        # do not copy dynamics information from /joint_states to internal robot monitoring
        # default to false, because almost nothing in move_group relies on this information
        ld.add_action(DeclareBooleanLaunchArg("monitor_dynamics", default_value=False))
        should_publish = LaunchConfiguration("publish_monitored_planning_scene")
        move_group_configuration = {
            "publish_robot_description_semantic": True,
            "allow_trajectory_execution": LaunchConfiguration("allow_trajectory_execution"),
            # Note: Wrapping the following values is necessary so that the parameter value can be the empty string
            "capabilities": ParameterValue(
                LaunchConfiguration("capabilities"), value_type=str
            ),
            "disable_capabilities": ParameterValue(
                LaunchConfiguration("disable_capabilities"), value_type=str
            ),
            # Publish the planning scene of the physical robot so that rviz plugin can know actual robot
            "publish_planning_scene": should_publish,
            "publish_geometry_updates": should_publish,
            "publish_state_updates": should_publish,
            "publish_transforms_updates": should_publish,
            "monitor_dynamics": False,
            "use_sim_time": True
        }
        move_group_params = [
            moveit_config.to_dict(),
            move_group_configuration,
        ]
        add_debuggable_node(
            ld,
            package="moveit_ros_move_group",
            executable="move_group",
            commands_file=str(moveit_config.package_path / "launch" / "gdb_settings.gdb"),
            output="screen",
            parameters=move_group_params,
            extra_debug_args=["--debug"],
            # Set the display variable, in case OpenGL code is used internally
            additional_env={"DISPLAY": ":0"},
        )
        return ld
    def generate_launch_description():
        moveit_config = MoveItConfigsBuilder("ur", package_name="ur_moveit").to_moveit_configs()
        return generate_move_group_launch(moveit_config)

You can observe how ` use_sim_time: True ` has been passed with the `
move_group_configuration ` dictionary.


Question:
Setting frame of IMU message in Gazebo Fortress

I am trying to setup a robot in Gazebo Fortress, under ROS2 Humble in Ubuntu 22.04. This robot has 6 wheels, a lidar and an IMU. I have setup the xacro files and I am able to spawn the robot into Gazebo and get laser and IMU readings.

However, the frame of the IMU messages is not correct. This is my IMU gazebo code in its corresponding xacro file:

    <gazebo reference="${prefix}_${imu_name}">
        <material>Gazebo/Black</material>
        <gravity>true</gravity>
        <sensor name="${prefix}_imu_sensor" type="imu">
            <always_on>true</always_on>
            <update_rate>25</update_rate>
            <visualize>false</visualize>
            <topic>${prefix}/imu</topic>
            <plugin filename="libignition-gazebo-imu-system.so" name="ignition::gazebo::systems::Imu">
            </plugin>
            <pose>0 0 0 0 0 0</pose>
        </sensor>
    </gazebo>
I have tried to add frameID to the plugin parameters, as I did in Gazebo Classic, but it didn't work. My questions are:

How to change the frame published in the messages?
What parameters are available for the IMU plugin? Is there any documentation or where can I read the source code?
Thank you!

Explanation: From the source code it appears you can use the tag gz_frame_id or the older ignition_frame_id (deprecated) as a child of the sensor tag.

$\begingroup$

From the source code it appears you can use the tag ` gz_frame_id ` or the
older ` ignition_frame_id ` (deprecated) as a child of the ` sensor ` tag.

The relevant source code is [ here ](https://github.com/gazebosim/gz-
sensors/blob/ec52913e608ce8f64053650bfcced84a70ca12e2/src/Sensor.cc#L158) .


Question:
ROS Environment variables not set after new Humble install on Ubuntu 22.04

I carefully followed the install instructions for installing ROS2 Humble binary.

https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html

The install had no errors. And I did the talker-listener test to make sure.

But none of the ROS environment variables are set.

When I type printenv I don't see ROS_VERSION=2,ROS_PYTHON_VERSION=3 or ROS_DISTRO=humble.

The tutorials page just says to go back to the installation page or get help from the community. So here I am :)

Thanks in advance!

Explanation: We can find examples about how to set environment variables in ros.

$\begingroup$

To have those environment variables exported in every command line
automatically, the easiest thing to do is to add ` export VARIABLE_NAME=VALUE
` for each one at the end of the ` ~/.bashrc ` file.

After saving, you need to open a new terminal window or call ` source
~/.bashrc ` for the changes to take effect.

**Edit:**

You shouldn't have to export those variables by yourself as those are taken
care of by the ` setup.bash ` script inside your ros humble instalation.

Please make sure you have your ros installation sourced in ` ~/.bashrc ` via `
source /opt/ros/humble/setup.bash `

[ Docs here ](https://wiki.ros.org/ROS/EnvironmentVariables)


Question:
ROS2 Map not received when using nav2_bringup

I'm currently using the TurtleBot2 on Ubuntu 22.04 Humble and successfully generated a map with ros2 launch nav2_bringup navigation_launch.py. I was able to use the command ros2 launch nav2_bringup bringup_launch.py map:=/name/of/path.yaml several times (it was showing the map sometimes and wasnt showing the map sometimes aswell) but now whenever I am launching the command it tells me

[component_container_isolated-1] [INFO] [1695317742.382350265] [global_costmap.global_costmap]: Timed out waiting for transform from base_link to map to become available, tf error: Invalid frame ID "map" passed to canTransform argument target_frame - frame does not exist

Opening the rviz config /nav2_bringup/rviz2/nav2_default_view.rviz results in Rviz2 telling me, that no map is received. I was trying to change the QoS aswell, which didnt have an impact at all.

I have looked into rqt_graph and /map was connected to global_cost_map, also I checked rqt and /map was not receiving any messages when I have monitored it in rqt.

Can someone help me out please?

Explanation: This is related to map server in nav2 system. We can check more details.

$\begingroup$

The nav2 map server is the one that puts the map into the /map topic, the map
is published once during launch and not continuously published. If you would
like to see the map again you could use the map server services, more info is
available here: [ https://github.com/ros-
planning/navigation2/blob/main/nav2_map_server/README.md
](https://github.com/ros-
planning/navigation2/blob/main/nav2_map_server/README.md)

More information can be provided if you share the logs.


Question:
In ROS, is it possible to do dynamic reconfigure with "nested" parameters?

Not positive I have the terminology right, but the idea is that I have a ROS 1 node that can have multiple "layers" of namespaces for some of the parameters. So the parameter list is something like:

/perception_node/map_size
/perception_node/sensor_1/max_range
/perception_node/sensor_2/max_range
It doesn't have to be set up this way, the key here is that there are multiple "sensor" objects that have the same parameter names, but can have different values. And the sensor names themselves should ideally be configurable from the launch file or a YAML file.

I'm able to get it up and running so that it all initializes correctly, I can have a sensor struct like this:

struct Sensor
{
    string sensor_name;  // < This gets set in the constructor
    float max_range;

    void configure(ros::NodeHandle & nodeHandle)
    {
        max_range = nodeHandle.param(sensor_name + "/max_range");
    }
};
And that works, but I'd really like to use dynamic reconfigure with this setup too. I've used dynamic reconfigure before on other projects, so I know the basics of creating a ".cfg" file and everything.

But dynamic reconfigure doesn't seem to like parameter names with "/" symbols in them, at least when I tried the following it failed to compile:

gen = ParameterGenerator()

gen.add("sensor_1/max_range", float_t ...etc....
My initial idea was that since the ".cfg" file is (I think) really a python file, I could do something clever here and read the sensor names from a configuration file rather than hard coding it like in the above example.

I also tried using groups, but it looks like you're not allowed to use the same parameter name more than once even if you do this:

sensor_1_params = gen.addGroup("sensor_1")
sensor_1_params.add("max_range", float_t ...etc...

sensor_2_params = gen.addGroup("sensor_2")
sensor_2_params.add("max_range", float_t ...etc... #Nope! This fails to compile too
The only thing I can think of right now is to get rid of the slashes, so that the parameters are called something like "sensor_1_max_range" and "sensor_2_max_range" and so on. The issue being that it would make the config callback kind of ugly, because on the C++ side I'd have to do something like:

if (sensor_name == "sensor_1") {
    max_range = config.sensor_1_max_range;
}
else if (sensor_name == "sensor_2") {
    max_range = config.sensor_2_max_range;
}
// And many more lines...
I also feel like this kind of defeats the purpose of having the sensor names in a configuration file, because now any time we want to add or remove sensors we need to edit the configuration file AND the C++ code.

So, I guess I'm wondering is it possible to actually do something like what I want? Have people had to deal with this before? Or am I better off restructuring things?

Explanation: We can check example usage of dynamic variables, which are associated with dynamic reconfigure.

$\begingroup$

Yes, multiple sets of dynamic_reconfigure parameters are supported for a
single ros node. You need to create a Server for each path that has this kind
of parameter. You can reuse a .cfg class name for different paths if you want
to.

An example is move_base, which provides dynamic parameters for multiple items
within its /move_base namespace. Each path is associated to a separate
dynamic_reconfigure::Server object. The following lines of code are from file
[ dwa_planner_ros.cpp in the navigation.git repo ](https://github.com/ros-
planning/navigation/blob/noetic-
devel/dwa_local_planner/src/dwa_planner_ros.cpp) , where ` name ` is a
relative path like "DWAPlannerROS":

    ros::NodeHandle private_nh("~/" + name);
    dsrv_ = new dynamic_reconfigure::Server<DWAPlannerConfig>(private_nh);

Take a look at the rest of that file to get the full picture.


Question:
Configuration wrt. automatic chaining of `setup.bash` prefix paths from `colcon build`

I recently found (to my great surprise) that upon issuing 'source install/setup.bash' for my ROS 2 install (built from source), that both Gazebo Sim and ros_gz_bridge were also sourced automatically.

So I had a look at the ROS 2 install/setup.bash script, and indeed it mentions:

# This script extends the environment with the environment of other prefix
# paths which were sourced when this file was generated as well as all packages
# contained in this prefix path.
So probably I did the following:

Compile and source ROS 2,
Compile and source Gazebo Sim,
Compile and source ros_gz_bridge,
Compile ROS 2 again.
I wonder if many people are aware of that behavior. In any case I did not know of this automatic chaining, nor was expecting it, as:

In above case, it is obviously undesirable that the ROS 2 setup.bash script would chain the Gazebo and ros_gz_bridge scripts,

But even in other cases this can be undesired. E.g. the ros_gz_bridge obviously depends on ROS 2 and Gazebo Sim, but even then I might want to source a different ROS 2 install (e.g. with some local changes, irrelevant to ros_gz_bridge). So I don't necessarily want the ros_gz_bridge to automatically source the ROS 2 install that was sourced at build time.

Is there some documentation wrt. this behavior?

Explanation: We can check the installation files of colcon, e.g., the functionality of setup and local_setup.

$\begingroup$

The answer is in the [ colcon documentation
](https://colcon.readthedocs.io/en/released/developer/environment.html#workspace-
level) :

  * ` local_setup.bash ` adds only that workspace to ` COLCON_PREFIX_PATH ` ,
  * ` setup.bash ` adds all workspaces to ` COLCON_PREFIX_PATH ` that were in the ` COLCON_PREFIX_PATH ` at the time of build.

So my best practice is to:

  * Open a separate terminal to compile,
  * Source only those workspaces that are strictly needed,
  * Use that terminal only to compile.

This avoids that I recompiled in a terminal where I had sourced other
workspaces (e.g. PlotJuggler) and then all of these other workspaces
unnecessarily end up in the ` setup.bash ` .


Question:
[ROS1 Noetic]Qt5 Rviz plugin

I'm having trouble making Rviz teleop plugin using Qtcreator. I'm using Noetic and Ubuntu 20.04.

The codes is not complete yet, for now I just want to see teleop GUI on Rviz. I'm using catkin_make_isolated --install build system

Error message: [ERROR] [1694503592.866043597]: PluginlibFactory: The plugin for class 'rviz_teleop_plugin/QtTeleopPanel' failed to load.  Error: Could not find library corresponding to plugin rviz_teleop_plugin/QtTeleopPanel. Make sure the plugin description XML file has the correct name of the library and that the library actually exists.

files: package name: rviz_teleop_plugin

CMakeLists.txt
package.xml
plugin_description.xml
src/qt_teleop_ui,cpp
include/rviz_teleop_plugin/qt_teleop_ui.h
cmake_minimum_required(VERSION 3.0.2)
project(rviz_teleop_plugin)

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  nav_msgs
  roscpp
  rospy
  rviz
  sensor_msgs
  std_msgs
)

find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5OpenGL REQUIRED)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(QT_LIBRARIES Qt5::Widgets)

add_definitions(-DQT_NO_KEYWORDS)

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES rviz_teleop_plugin
  CATKIN_DEPENDS geometry_msgs nav_msgs roscpp rospy rviz sensor_msgs std_msgs
  # DEPENDS system_lib
)

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
  ${Qt5Widgets_INCLUDE_DIRS}
)

link_directories(${catkin_LIBRARY_DIRS})

qt5_wrap_cpp(MOC_FILES
  include/rviz_teleop_plugin/qt_teleop_ui.h
)

set(SOURCE_FILES
  src/qt_teleop_ui.cpp
  ${MOC_FILES}
)

add_library(${PROJECT_NAME}
  ${SOURCE_FILES}
)

add_dependencies(rviz_teleop_plugin ${PROJECT_NAME_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(${PROJECT_NAME}
  Qt5::Widgets
  ${QT_LIBRARIES}
  ${catkin_LIBRARIES}
)

install(TARGETS
  ${PROJECT_NAME}
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

install(DIRECTORY include/${PROJECT_NAME}/ rviz
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)

install(FILES plugin_description.xml
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)

set_target_properties(rviz_teleop_plugin PROPERTIES OUTPUT_NAME "rviz_teleop_plugin")
<?xml version="1.0"?>
<package format="2">
  <name>rviz_teleop_plugin</name>
  <version>0.0.0</version>
  <description>The rviz_teleop_plugin package</description>

  <maintainer email="cabmintt@gmail.com">minseojeong</maintainer>
  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>

  <build_depend>geometry_msgs</build_depend>
  <build_depend>nav_msgs</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>rviz</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_depend>std_msgs</build_depend>

  <build_depend>qt_gui_cpp</build_depend>
  <build_depend>qtbase5-dev</build_depend>
  <build_depend>libqt5-core</build_depend>
  <build_depend>libqt5-gui</build_depend>
  <build_depend>libqt5-widgets</build_depend>

  <build_export_depend>geometry_msgs</build_export_depend>
  <build_export_depend>nav_msgs</build_export_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>rviz</build_export_depend>
  <build_export_depend>sensor_msgs</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>

  <build_export_depend>qt_gui_cpp</build_export_depend>
  <build_export_depend>qtbase5-dev</build_export_depend>
  <build_export_depend>libqt5-core</build_export_depend>
  <build_export_depend>libqt5-gui</build_export_depend>
  <build_export_depend>libqt5-widgets</build_export_depend>

  <exec_depend>geometry_msgs</exec_depend>
  <exec_depend>nav_msgs</exec_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>rviz</exec_depend>
  <exec_depend>sensor_msgs</exec_depend>
  <exec_depend>std_msgs</exec_depend>

  <exec_depend>qt_gui_cpp</exec_depend>
  <exec_depend>qtbase5-dev</exec_depend>
  <exec_depend>libqt5-core</exec_depend>
  <exec_depend>libqt5-gui</exec_depend>
  <exec_depend>libqt5-widgets</exec_depend>

  <export>
    <rviz plugin="${prefix}/plugin_description.xml"/>
  </export>

</package>
<!-- <library path="lib/librviz_teleop_plugin"> -->
<library path="install_isolated/lib/librviz_teleop_plugin.so">
  <class name="rviz_teleop_plugin/QtTeleopPanel"
         type="rviz_teleop_plugin::QtTeleopPanel"
         base_class_type="rviz::Panel">
    <description>
      A Teleop Panel to control the robot.
    </description>
    <qtgui>
      <name>rviz_teleop_plugin/QtTeleopPanel</name>
      <class>rviz_teleop_plugin::QtTeleopPanel</class>
      <label>Teleop Panel</label>
    </qtgui>
  </class>
</library>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QDoubleSpinBox>
// #include <QtWidgets/QPainter>
// #include <QtWidgets/QLineEdit>

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
#include <QtWidgets/QSlider>

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
// #include <rviz/panel.h>

#include "rviz_teleop_plugin/qt_teleop_ui.h"

class QtTeleopPanel;

namespace rviz_teleop_plugin
{
    QtTeleopPanel::QtTeleopPanel(QWidget* parent)
        : rviz::Panel(parent),
        // : QWidget(parent),
          nh_("~"),
          cmd_vel_pub_(nh_.advertise<geometry_msgs::Twist>("cmd_vel", 1))

    {
        QVBoxLayout* layout = new QVBoxLayout;

        QLabel* X_label = new QLabel("X ::");
        QDoubleSpinBox* X_doubleSpinBox = new QDoubleSpinBox;
        X_doubleSpinBox->setMaximum(1.0);
        X_doubleSpinBox->setSingleStep(0.01);

        QLabel* Y_label = new QLabel("Y ::");
        QDoubleSpinBox* Y_doubleSpinBox = new QDoubleSpinBox;
        Y_doubleSpinBox->setMaximum(1.0);
        Y_doubleSpinBox->setSingleStep(0.01);

        QPushButton* Send_Button = new QPushButton("Send");
        QPushButton* Up_Button = new QPushButton("UP");
        QPushButton* Stop_Button = new QPushButton("Stop");
        QPushButton* Down_Button = new QPushButton("Down");
        QPushButton* Left_Button = new QPushButton("Left");
        QPushButton* Right_Button = new QPushButton("Right");

        QLabel* Linear_label = new QLabel("Linear vel");
        QDoubleSpinBox* Linear_doubleSpinBox = new QDoubleSpinBox;
        Linear_doubleSpinBox->setMaximum(1.0);
        Linear_doubleSpinBox->setSingleStep(0.01);

        QLabel* Angular_label = new QLabel("Angular vel");
        QDoubleSpinBox* Angular_doubleSpinBox = new QDoubleSpinBox;
        Angular_doubleSpinBox->setMaximum(1.0);
        Angular_doubleSpinBox->setSingleStep(0.1);

        layout->addWidget(X_label);
        layout->addWidget(X_doubleSpinBox);
        layout->addWidget(Y_label);
        layout->addWidget(Y_doubleSpinBox);
        layout->addWidget(Send_Button);
        layout->addWidget(Up_Button);
        layout->addWidget(Stop_Button);
        layout->addWidget(Down_Button);
        layout->addWidget(Left_Button);
        layout->addWidget(Right_Button);
        layout->addWidget(Linear_label);
        layout->addWidget(Linear_doubleSpinBox);
        layout->addWidget(Angular_label);
        layout->addWidget(Angular_doubleSpinBox);

        QWidget::setLayout(layout);

        QObject::connect(Up_Button, SIGNAL(clicked()), this, SLOT(on_Up_Button_pressed()));
        QObject::connect(Down_Button, SIGNAL(clicked()), this, SLOT(on_Down_Button_pressed()));
        QObject::connect(Left_Button, SIGNAL(clicked()), this, SLOT(on_Left_Button_pressed()));
        QObject::connect(Right_Button, SIGNAL(clicked()), this, SLOT(on_Right_Button_pressed()));
        QObject::connect(Stop_Button, SIGNAL(clicked()), this, SLOT(on_Stop_Button_pressed()));
        QObject::connect(Send_Button, SIGNAL(clicked(bool)), this, SLOT(on_Send_Button_clicked(bool)));
        QObject::connect(X_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_X_doubleSpinBox_valueChanged(double)));
        QObject::connect(Y_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_Y_doubleSpinBox_valueChanged(double)));
        QObject::connect(Linear_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_Linear_doubleSpinBox_valueChanged(double)));
        QObject::connect(Angular_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_Angular_doubleSpinBox_valueChanged(double)));
    }

    void QtTeleopPanel::on_Up_Button_pressed()
    {
        geometry_msgs::Twist cmd_vel;
        cmd_vel.linear.x = this->Linear_doubleSpinBox->value();
        cmd_vel.angular.z = this->Angular_doubleSpinBox->value();

        cmd_vel_pub_.publish(cmd_vel);
    }

    void QtTeleopPanel::on_Down_Button_pressed()
    {
        geometry_msgs::Twist cmd_vel;
        cmd_vel.linear.x = -this->Linear_doubleSpinBox->value();
        cmd_vel.angular.z = -this->Angular_doubleSpinBox->value();

        cmd_vel_pub_.publish(cmd_vel);
    }

    void QtTeleopPanel::on_Left_Button_pressed()
    {
        geometry_msgs::Twist cmd_vel;
        cmd_vel.linear.x = 0.0;
        cmd_vel.angular.z = this->Angular_doubleSpinBox->value();

        cmd_vel_pub_.publish(cmd_vel);
    }

    void QtTeleopPanel::on_Right_Button_pressed()
    {
        geometry_msgs::Twist cmd_vel;
        cmd_vel.linear.x = 0.0;
        cmd_vel.angular.z = -this->Angular_doubleSpinBox->value();

        cmd_vel_pub_.publish(cmd_vel);
    }

    void QtTeleopPanel::on_Stop_Button_pressed()
    {
        geometry_msgs::Twist cmd_vel;
        cmd_vel.linear.x = 0.0;
        cmd_vel.angular.z = 0.0;

        cmd_vel_pub_.publish(cmd_vel);
    }

    void QtTeleopPanel::on_Send_Button_clicked(bool checked)
    {
    }

    void QtTeleopPanel::on_X_doubleSpinBox_valueChanged(double arg1)
    {
    }

    void QtTeleopPanel::on_Y_doubleSpinBox_valueChanged(double arg1)
    {
    }

    void QtTeleopPanel::on_Linear_doubleSpinBox_valueChanged(double arg1)
    {
    }

    void QtTeleopPanel::on_Angular_doubleSpinBox_valueChanged(double arg1)
    {
    }

} // namespae

#include <pluginlib/class_list_macros.h>
PLUGINLIB_EXPORT_CLASS(rviz_teleop_plugin::QtTeleopPanel, rviz::Panel)
/********************************************************************************
** Form generated from reading UI file 'qt_teleop.ui'
**
** Created by: Qt User Interface Compiler version 5.12.8
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

// #ifndef QT_TELEOP_UI_H
// #define QT_TELEOP_UI_H

#ifndef QT_TELEOP_UI_H
#define QT_TELEOP_UI_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
#include <QtWidgets/QSlider>
#include <QtWidgets/QVBoxLayout>

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <rviz/panel.h>

// QT_BEGIN_NAMESPACE

namespace rviz_teleop_plugin
{
    // class QtTeleopPanel : public QWidget
    class QtTeleopPanel : public rviz::Panel
    {
        Q_OBJECT

    public:
        QtTeleopPanel(QWidget *parent = 0);
        // ~QtTeleopPanel();

    public Q_SLOTS:
        void on_Up_Button_pressed();
        void on_Down_Button_pressed();
        void on_Left_Button_pressed();
        void on_Right_Button_pressed();
        void on_Stop_Button_pressed();
        void on_Send_Button_clicked(bool checked);
        void on_X_doubleSpinBox_valueChanged(double arg1);
        void on_Y_doubleSpinBox_valueChanged(double arg1);
        void on_Linear_doubleSpinBox_valueChanged(double arg1);
        void on_Angular_doubleSpinBox_valueChanged(double arg1);

    private:
        ros::NodeHandle nh_;
        ros::Publisher cmd_vel_pub_;

        QWidget *centralwidget;
        QLabel *X_label;
        QDoubleSpinBox *X_doubleSpinBox;
        QLabel *Y_label;
        QDoubleSpinBox *Y_doubleSpinBox;
        QPushButton *Send_Button;
        QPushButton *Up_Button;
        QPushButton *Stop_Button;
        QPushButton *Down_Button;
        QPushButton *Left_Button;
        QPushButton *Right_Button;
        QDoubleSpinBox *Linear_doubleSpinBox;
        QLabel *Linear_label;
        QLabel *Angular_label;
        QDoubleSpinBox *Angular_doubleSpinBox;
        QMenuBar *menubar;
        QMenu *menuteleop_panel;
        QStatusBar *statusbar;
    };

} // end namespace

// QT_END_NAMESPACE

#endif // QT_TELEOP_UI_H

Explanation: We need to check the TeleopPanel rviz tutorial about how to write a simple Panel plugin for RViz.

$\begingroup$

A plugin for a ros node (which rviz is) is usually not built using an isolated
build. I suggest that you review the ` TeleopPanel ` rviz tutorial at this url
(but ignore the part where it refers to the older ` rosmake ` command):

[ http://docs.ros.org/en/kinetic/api/rviz_plugin_tutorials/html/
](http://docs.ros.org/en/kinetic/api/rviz_plugin_tutorials/html/)

The fully buildable code is available at:

[ https://github.com/ros-visualization/visualization_tutorials.git
](https://github.com/ros-visualization/visualization_tutorials.git)

It builds with catkin_make. Make sure you are using the correct branch e.g.
noetic-devel.


Question:
Building example library of ROS 2

I am trying to build the example repository of ROS 2 Humble according to the tutorial. But the command colcon build --symlink-install gives the following error for all python packages. I am on Ubuntu 22.04.

What could be the reason for that?

Failed   <<< examples_rclpy_pointcloud_publisher [0.86s, exited with code 1]
    --- stderr: launch_testing_examples
    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/colcon_core/executor/__init__.py", line 91, in __call__
        rc = await self.task(*args, **kwargs)
      File "/usr/lib/python3/dist-packages/colcon_core/task/__init__.py", line 93, in __call__
        return await task_method(*args, **kwargs)
      File "/usr/lib/python3/dist-packages/colcon_ros/task/ament_python/build.py", line 51, in build
        setup_py_data = get_setup_data(self.context.pkg, env)
      File "/usr/lib/python3/dist-packages/colcon_core/task/python/__init__.py", line 20, in get_setup_data
        return dict(pkg.metadata[key](env))
      File "/usr/lib/python3/dist-packages/colcon_ros/package_augmentation/ros_ament_python.py", line 57, in getter
        return get_setup_information(
      File "/usr/lib/python3/dist-packages/colcon_python_setup_py/package_identification/python_setup_py.py", line 241, in get_setup_information
        _setup_information_cache[hashable_env] = _get_setup_information(
      File "/usr/lib/python3/dist-packages/colcon_python_setup_py/package_identification/python_setup_py.py", line 293, in _get_setup_information
        return ast.literal_eval(output)
      File "/usr/lib/python3.10/ast.py", line 64, in literal_eval
        node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
      File "/usr/lib/python3.10/ast.py", line 50, in parse
        return compile(source, filename, mode, flags,
      File "<unknown>", line 1
        {'package_data': {}, 'dist_files': [], 'src_root': None, 'dependency_links': [], 'setup_requires': [], 'eager_resources': None, 'entry_points': {'console_scripts': []}, 'exclude_package_data': None, 'extras_require': {}, 'include_package_data': None, 'install_requires': ['setuptools'], 'namespace_packages': None, 'packages': ['launch_testing_examples'], 'python_requires': None, 'test_loader': None, 'test_runner': None, 'test_suite': None, 'tests_require': ['pytest'], 'use_2to3': None, 'zip_safe': True, 'verbose': 1, 'dry_run': 0, 'help': 0, 'command_packages': None, 'script_name': 'setup.py', 'script_args': ['--dry-run'], 'command_options': {'develop': {'script_dir': ('setup.cfg', '$base/lib/launch_testing_examples')}, 'install': {'install_scripts': ('setup.cfg', '$base/lib/launch_testing_examples')}}, 'package_dir': {}, 'py_modules': None, 'libraries': None, 'headers': None, 'ext_package': None, 'include_dirs': None, 'extra_path': None, 'scripts': None, 'data_files': [('share/ament_index/resource_index/packages', ['resource/launch_testing_examples']), ('share/launch_testing_examples', ['package.xml'])], 'password': '', 'command_obj': {}, 'have_run': {}, 'want_user_cfg': True, 'metadata': {'name': 'launch_testing_examples', 'version': '0.15.1', 'author': None, 'author_email': None, 'maintainer': 'Aditya Pande, Shane Loretz', 'maintainer_email': 'aditya.pande@openrobotics.org, shane@openrobotics.org', 'url': None, 'license': 'Apache License 2.0', 'description': 'Examples of simple launch tests', 'long_description': None, 'keywords': None, 'platforms': None, 'classifiers': None, 'download_url': None, 'provides': None, 'requires': None, 'obsoletes': None, 'long_description_content_type': None, 'project_urls': {}, 'license_file': None, '_normalized_install_requires': {'setuptools': <Requirement('setuptools')>}, '_normalized_extras_require': {}}}
                                                                                ^
    SyntaxError: invalid syntax
I reinstalled ROS 2 but it did not resolve the problem. What else could I try?

Explanation: We can check whether this is caused by setuptools.

$\begingroup$

This appears to be a recent break with a particular version of setuptools
which has been reported in [ pypa/setuptools#4046
](https://github.com/pypa/setuptools/issues/4046) and [ colcon/colcon-python-
setup-py#56 ](https://github.com/colcon/colcon-python-setup-py/issues/56) .

A working mitigation is to upgrade the setuptools version in the ROS2 shell to
` >68.2.0 ` with the following command:

    # replace iron with your installed version of ROS2
    source /opt/ros/iron/local_setup.bash
    python3 -m pip install -U setuptools>68.2.0

After this, you should be able to build.


Question:
How to deserialize ROS messages from Bag to ROS defined types in C++?

I want to deserialize messages from a Bag file and publishing part of their contents with ROS for further processing.

I read a bagfile with the ROS C++ API. I know exactly the content (topic names and types) of my messages at compile time, such that I want to deserialize it into common ROS defined classes (e.g. the ones defined here https://docs.ros.org/en/noetic/api/sensor_msgs/html/index-msg.html) at runtime. Here some code:

#include <rosbag/bag.h>
#include <rosbag/view.h>
//other content
  rosbag::Bag bag;
  bag.open("foo.bag", rosbag::bagmode::Read);

  std::vector<std::string> topics{"camera1/camera_info"};

  rosbag::View view(bag, rosbag::TopicQuery(topics));

  for(auto const m : view)
  {
      const std::string& topic_name = m.getTopic();
      std::cout << topic_name << std::endl;
      std_msgs::String::ConstPtr s = m.instantiate<std_msgs::String>();
      if (s != NULL)
          std::cout << s->data << std::endl;

      // I want the data in s as a string to be serialized into an instance
      // of the type CameraInfo located in
      // path/ros/distro/sensor_msgs/CameraInfo.h shipping with ROS.
      CameraInfo ci = is_there_any_os_solution(s); //?
  }

  bag.close();
I tried to find something on this direction but I just found libraries deserializing contents unknown at compile time.

Could anyone give some hints?

Explanation: This is related to instantiate method on the rosbag MessageInstance. We may check the documentation for details.

$\begingroup$

I think that you're looking for the [ ` instantiate ` method
](https://docs.ros.org/en/api/rosbag_storage/html/c++/classrosbag_1_1MessageInstance.html#a369b32708a1a8bdaad133a47152a4885)
on the rosbag ` MessageInstance `

There's a very minimal example [ here
](https://docs.ros.org/en/api/rosbag_storage/html/c++/)

    BOOST_FOREACH(rosbag::MessageInstance const m, view)
    {
        std_msgs::Int32::ConstPtr i = m.instantiate<std_msgs::Int32>();
    ...

And more examples [ here ](http://wiki.ros.org/rosbag/Code%20API) and a [
cookbook of examples using the rosbag API
](http://wiki.ros.org/rosbag/Cookbook) .


Question:
Can't find Apply Force Torque plugin in gazebo garden

Environment: OS: Linux Ubuntu 22.04 gazebo version: garden

Problem: When I‘m following the tutorial here, I can't find Apply Force Torque plugin
Does my gazebo need update or there's something wrong?

Explanation: One possible cause is that the functionalities have not been merged. We can check the instructions to install from the source.

$\begingroup$

That functionality was only very recently merged, so probably the packages
haven't been updated yet. If you can't wait for the updated packages, you can
compile Gazebo from source. This is not particularly difficult, just follow [
the instructions ](https://gazebosim.org/docs/harmonic/install_ubuntu_src) .


Question:
Set interface name without msg in ROS2

When creating custom message types in ROS1 (noetic), I can store the *.msg files in a subfolder named msg. In the CMake file, I just type the name of the file without msg/ in add_message_files(...). The resulting message type is named as <pkg_name>/<file-name (without .msg)>

When creating interfaces in ROS2 (foxy), I have to type the file name in my CMake file including the relative path in rosidl_generate_interfaces(...) like msg/<filename.msg>. The resulting interface name also includes msg: <pkg_name>/msg/<file-name (without .msg)>, but actually I don't want the exact path as an interface name.

So my question is: Is it possible to store the files in the msg folder for a better folder structure but set the name of the resulting interface differently?

Explanation: We need to check the documentation and usage of configure_file. We may change the file destination in the parameters.

$\begingroup$

You certainly _can_ change the destination of any files produced by CMake
(using, for example, the [ ` configure_file() ` command
](https://cmake.org/cmake/help/latest/command/configure_file.html) ).

But... _should_ you? I'm not convinced that you should. I think you'll find
you have cleaner code if you allow messages to be explicitly stored alongside
only other messages. Further, having a standard behavior for generated files
is very useful for other developers: anyone using your package will assume
that messages will take place in a standard location. Even in the cases where
nobody else will use your code, the ROS tools you're running on your computer
will often make this assumption.

As an experiment, try changing the files manually (using the ` mv ` command or
your file explorer) and see what breaks. I think you'll find that this ends up
being messier than you initially bargained for.