[ROS Q&A] 146 – Command line argument passing in rosrun

 

In this video we are going to explore how to pass an argument through command line using rosrun.

It can be a bit confusing, but we are going to explain the difference of the return of the method depending of the type of the value you pass to the argument.

 

Step 1. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here. Let’s call the project rosrun_param.

Step 2. Create package

We’ll create a package for our code with the roscpp and std_msgs dependency.

cd ~/catkin_ws/src
catkin_create_pkg my_pkg roscpp std_msgs

Under the my_pkg/src folder, create a my_pkg_node.cpp file with the code from the question.

#include <ros/ros.h>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{  
  std::string param;
  ros::init(argc, argv, "node_name");
  ros::NodeHandle nh("~");
  ROS_INFO("Got parameter : %s", param.c_str());

  if(nh.getParam("blue", param))
  {
    cout << "blue" << endl;
  }
  else if(nh.getParam("green", param))
  {
    cout<< "green" << endl;
  }        
  else
  {
    cout << "Don't run anything !! " << endl;
  }
  return 0;
}

To compile the code, we have to modify the CMakeLists.txt file. Please uncomment the add_executable and target_link_libraries in the build part.

Then we can compile the code with

cd ~/catkin_ws
catkin_make

After compile, we can run the executable with

rosrun my_pkg my_pkg_node

The output is just don’t run anything because we didn’t pass any argument yet.

As an example, we can pass arguments like the following

rosrun my_pkg my_pkg_node _blue:=text

Then the output is blue.

However, the code doesn’t quite make sense. Let’s modify it.

#include <ros/ros.h>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{  
  std::string param;
  ros::init(argc, argv, "node_name");
  ros::NodeHandle nh("~");
  nh.getParam("param", param)
  ROS_INFO("Got parameter : %s", param.c_str());

  if(param.compare("blue")==0)
  {
    cout << "blue" << endl;
  }
  else if(param.compare("green")==0)
  {
    cout<< "green" << endl;
  }        
  else
  {
    cout << "Don't run anything !! " << endl;
  }
  return 0;
}

Now if you pass blue or green as arguments, it will print the color. If you pass something else, it will run nothing.

Want to learn more?

If you are interested in ROS and want to learn more about it, please check our ROS Basics C++ Course.

 

Edit by: Tony Huang

RELATED LINKS

ROS Development Studio (RDS)
Robot Ignite Academy
ROS Basics C++ Course

 


Feedback

Did you like this video? Do you have questions about what is explained? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know on the comments area and we will do a video about it.

[ROS Q&A] 145 – Customize plot axis with rqt_multiplot

In this video we are going to see how to customize the axis of your plot, using the rqt_multiplot tool.

Step1. Create a project in Robot Ignite Academy(RIA)

We have the best online ROS course available in RIA. It helps you learn ROS in the easiest way without setting up ROS environment locally. The only thing you need is a browser! Create an account here and start to browse the trial course for free now! We’ll use the Using OpenAI with ROS unit 0 as an example today.

Step2. Plot with rqt_plot and rqt_multiplot

Let’s start by running the example

roslaunch cartpole_v0_training start_training.launch

You’ll see that the robot starts to move and learning to stand. The reward of each episode is publishing to the topic /openai/reward. You can see that with the following command

rostopic echo /openai/reward

It’s hard to tell the trend of the reward in the terminal. It will be nicer if we can plot it into a figure. We can use the rqt_plot tool to do it. You can run the following command to open rqt_plot.

rosrun rqt_plot rqt_plot

Then you have to open the graphical tool by click the monitor icon next to the simulation.

You can select the topic that you want to plot in rqt_plot. Let’s type openai/reward.  The tool plot the reward for us, but it’s not updating.

With rqt_plot, the x-axis is always the timestamp. The problem is, in openai gym, the environment keeps resetting itself, so the reward value is overriding itself.

To solve this problem, we need another tool called rqt_multiplot.

rosrun rqt_multiplot rqt_multiplot

After opening it, click on the configure plot button(gear shape) and select the /openai/reward topic again. We select the episode number as our x-axis and the reward as our y-axis. Then hit enter.

Select the curve and click ok. Then click the play button. You should see it’s plotting. The rewards over episodes plot show the training progress much better in this case!

Want to learn more?

If you are interested in this topic, you can check our Using OpenAI with ROS Online Course.

 

Edit by: Tony Huang


RELATED LINKS

ROS Development Studio (RDS)
Robot Ignite Academy
Using OpenAI with ROS Online Course


Feedback

Did you like this video? Do you have questions about what is explained? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know on the comments area and we will do a video about it.

[ROS Q&A] 144 – What is the difference between ROS topics and messages?

In this video we are going to explain and show in a practical way the difference between ROS topics and messages.

We show two nodes running, one publishing to a given topic and another subscribing to this same topic. RQT graph is used to see the big picture of the environment.

 

Step 0. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here. Let’s create a new project and call it ros_q_a_topics_messages.

Step 1. Difference between ros topic and ros message

We’ll start by creating a package for the code in catkin_ws

cd catkin_ws/src
catkin_create_pkg my_pkg rospy std_msgs

Let’s also create a scripts folder for our scripts. Then two script called my_subscriber.py and my_publisher.py file in it with the following content.

#!/usr/bin/env python

import rospy
from std_msgs.msg import String

def main():
    pub = rospy.Publisher('my_topic', String, queue_size=10)
    rospy.init_node('my_publisher')

    rate = rospy.Rate(1)
    
    while not rospy.is_shutdown():
        hello_str = 'hello world %s' % rospy.get_time()

        rospy.loginfo(hello_str)

        pub.publish(hello_str)

        rate.sleep()

if __name__ == '__main__':
    try:
        main()
    except rospy.ROSInterruptExeception:
        pass

Basically, a message is data through a channel called topic. In this code, the message is String type and the topic is called my_topic.

#!/usr/bin/env python

import rospy
from std_msgs import String

def main():
    pub = rospy.Publisher('my_topic', String, queue_size = 10)

    rospy.init_node('my_publisher')

    rate = rospy.Rate(1)

    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()

        rospy.loginfo(hello_str)

        pub.publish(hello_str)

        rate.sleep()

if __name__ == '__main__' :
    try:
        main()
    except rospy.ROSInterruptExeception:
        pass

This script established a subscriber for the message through the topic my_topic.

To run the code, we have to give the scripts permission to execute with chmod +x my_publisher.py and chmod +x my_subscriber.py

Then we can run it with

cd catkin_ws
catkin_make
source devel/setup.bash
rosrun my_pkg my_publisher.py

You should see the publisher is publishing message into the topic.

Open another shell and run

rosrun my_pkg my_subscriber.py

Open the third shell and type rqt_graph , then go to Tools->graphical tool to open the GUI.

You should see the nodes are marked with circles. You can find the /my_publisher and /my_subscriber nodes in the graph.

The topic is marked with the square. In this example, the topic is called my_topic. The two node is communicating though this topic.

Want to learn more?

If you are interested in learning ROS, please check our ROS Basics Python course.

 

Edit by: Tony Huang


RELATED LINKS

▸ Original question: https://answers.ros.org/question/63511/what-is-the-difference-between-a-topic-and-a-message/
ROS Development Studio (ROSDS)
Robot Ignite Academy
ROS Basics Python
ROS Basics C++


Feedback

Did you like this video? Do you have questions about what is explained? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know on the comments area and we will do a video about it.

[ROS Projects] – Use OpenAI_ROS with TurtleBot2 Step-by-Step #Part 2

[ROS Projects] – Use OpenAI_ROS with TurtleBot2 Step-by-Step #Part 2

 

In this second part, you will continue by creating your own TaskEnvironment for a different TurtleBot simulation environment with a wall.
You will create this Task Env that allows the robot to learn how to reach a certain position in the map without running into the wall.

Related links and resources:

[irp posts=”10259″ name=”[ROS Projects] – Use OpenAI_ROS with Turtlebot2 Step by Step #Part 1″]

[ROS Q&A] 143 – How to connect MoveIt to the Robot

In this tutorial of ROS Q&A Series, we’re going to see how to connect movit to the (simulated, in this case) robot.

This is a video trying to answer the following question posted at the ROS answers forum: https://answers.ros.org/question/298508/how-do-i-interact-the-actual-robot-with-visualization-by-rviz-in-moveit/

Step 1. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here. Let’s create a new project and call it moveit_real.

Step 2. Use the moveit package

In this tutorial, we have already preconfigured the Sia Robot and moveit package for it. If you want to know how to configure the moveit package, please check our ROS-Industrial 101 course. If you launch the moveit package, you’ll see that no matter what trajectory you are planning in the moveit, it won’t affect the real robot(we use a simulation as an example here). That’s because of missing controllers. To apply the controller, a file called controller.yaml should be created in the config folder of the robot. We also have to specify the controller type in the sia10f.urdf file.  In order to use the controller, a transmission tag should be added to the urdf. You’ll also need a joint_names.yaml file in the config folder which defines the joints will be controlled. In the end, you’ll need to create launch files to launch the package.

Step 3. Plan the trajectory

After launching the controller, you can plan the trajectory with moveit package. The robot should move as the planning in the moveit package.

Want to learn more?

If you are interested in this topic and want to learn how to configure the moveit package and all the files you need to move the robot, please check our ROS-Industrial 101 course.

 

Edit by: Tony Huang

 

Related Courses

ROS Manipulation Course Cover - ROS Online Courses - Robot Ignite Academy

ROS Manipulation Course


Feedback

Did you like this video? Do you have questions about what is explained? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know on the comments area and we will do a video about it.

[ROS Q&A] 142 – How to create launch file for URDF and open in Gazebo

In this video, we are going to show how to create a launch file to spawn a URDF robot model in a given gazebo world.

Up to the end of the video, you will be able to spawn any robot model you may have described in URDF in Gazebo.

Step 1. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here. Let’s create a new project and call it launch_urdf_model_in_gazebo.

Step 2. Create a package

Let’s create a ROS package for our code by using the following command.

cd ~/catkin_ws/src
catkin_create_pkg my_robot_urdf rospy

Then we create a m2wr.urdf file under the my_robot_urdf/urdf folder.

<?xml version="1.0"?>
<robot name="m2wr" xmlns:xacro="http://www.ros.org/wiki/xacro">
  <material name="black">
    <color rgba="0.0 0.0 0.0 1.0"/>
  </material>
  <material name="blue">
    <color rgba="0.203125 0.23828125 0.28515625 1.0"/>
  </material>
  <material name="green">
    <color rgba="0.0 0.8 0.0 1.0"/>
  </material>
  <material name="grey">
    <color rgba="0.2 0.2 0.2 1.0"/>
  </material>
  <material name="orange">
    <color rgba="1.0 0.423529411765 0.0392156862745 1.0"/>
  </material>
  <material name="brown">
    <color rgba="0.870588235294 0.811764705882 0.764705882353 1.0"/>
  </material>
  <material name="red">
    <color rgba="0.80078125 0.12890625 0.1328125 1.0"/>
  </material>
  <material name="white">
    <color rgba="1.0 1.0 1.0 1.0"/>
  </material>
  
    <gazebo reference="link_chassis">
    <material>Gazebo/Orange</material>
  </gazebo>
  <gazebo reference="link_left_wheel">
    <material>Gazebo/Blue</material>
  </gazebo>
  <gazebo reference="link_right_wheel">
    <material>Gazebo/Blue</material>
  </gazebo>
  
  <gazebo>
    <plugin filename="libgazebo_ros_diff_drive.so" name="differential_drive_controller">
      <alwaysOn>true</alwaysOn>
      <updateRate>20</updateRate>
      <leftJoint>joint_left_wheel</leftJoint>
      <rightJoint>joint_right_wheel</rightJoint>
      <wheelSeparation>0.4</wheelSeparation>
      <wheelDiameter>0.2</wheelDiameter>
      <torque>0.1</torque>
      <commandTopic>cmd_vel</commandTopic>
      <odometryTopic>odom</odometryTopic>
      <odometryFrame>odom</odometryFrame>
      <robotBaseFrame>link_chassis</robotBaseFrame>
    </plugin>
  </gazebo>
  
  <gazebo reference="sensor_laser">
    <sensor type="ray" name="head_hokuyo_sensor">
      <pose>0 0 0 0 0 0</pose>
      <visualize>false</visualize>
      <update_rate>20</update_rate>
      <ray>
        <scan>
          <horizontal>
            <samples>720</samples>
            <resolution>1</resolution>
            <min_angle>-1.570796</min_angle>
            <max_angle>1.570796</max_angle>
          </horizontal>
        </scan>
        <range>
          <min>0.10</min>
          <max>10.0</max>
          <resolution>0.01</resolution>
        </range>
        <noise>
          <type>gaussian</type>
          <mean>0.0</mean>
          <stddev>0.01</stddev>
        </noise>
      </ray>
      <plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_laser.so">
        <topicName>/m2wr/laser/scan</topicName>
        <frameName>sensor_laser</frameName>
      </plugin>
    </sensor>
  </gazebo>
  
   <link name="link_chassis">
    <!-- pose and inertial -->
    <pose>0 0 0.1 0 0 0</pose>
    <inertial>
      <mass value="5"/>
      <origin rpy="0 0 0" xyz="0 0 0.1"/>
      <inertia ixx="0.0395416666667" ixy="0" ixz="0" iyy="0.106208333333" iyz="0" izz="0.106208333333"/>
    </inertial>
    <!-- body -->
    <collision name="collision_chassis">
      <geometry>
        <box size="0.5 0.3 0.07"/>
      </geometry>
    </collision>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <box size="0.5 0.3 0.07"/>
      </geometry>
      <material name="blue"/>
    </visual>
    <!-- caster front -->
    <collision name="caster_front_collision">
      <origin rpy=" 0 0 0" xyz="0.35 0 -0.05"/>
      <geometry>
        <sphere radius="0.05"/>
      </geometry>
      <surface>
        <friction>
          <ode>
            <mu>0</mu>
            <mu2>0</mu2>
            <slip1>1.0</slip1>
            <slip2>1.0</slip2>
          </ode>
        </friction>
      </surface>
    </collision>
    <visual name="caster_front_visual">
      <origin rpy=" 0 0 0" xyz="0.2 0 -0.05"/>
      <geometry>
        <sphere radius="0.05"/>
      </geometry>
    </visual>
  </link>
  
  <link name="link_right_wheel">
    <inertial>
      <mass value="0.2"/>
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <inertia ixx="0.000526666666667" ixy="0" ixz="0" iyy="0.000526666666667" iyz="0" izz="0.001"/>
    </inertial>
    <collision name="link_right_wheel_collision">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </collision>
    <visual name="link_right_wheel_visual">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </visual>
  </link>
  
  <joint name="joint_right_wheel" type="continuous">
    <origin rpy="0 0 0" xyz="-0.05 0.15 0"/>
    <child link="link_right_wheel"/>
    <parent link="link_chassis"/>
    <axis rpy="0 0 0" xyz="0 1 0"/>
    <limit effort="10000" velocity="1000"/>
    <joint_properties damping="1.0" friction="1.0"/>
  </joint>
  
  <link name="link_left_wheel">
    <inertial>
      <mass value="0.2"/>
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <inertia ixx="0.000526666666667" ixy="0" ixz="0" iyy="0.000526666666667" iyz="0" izz="0.001"/>
    </inertial>
    <collision name="link_left_wheel_collision">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </collision>
    <visual name="link_left_wheel_visual">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </visual>
  </link>
  
  <joint name="joint_left_wheel" type="continuous">
    <origin rpy="0 0 0" xyz="-0.05 -0.15 0"/>
    <child link="link_left_wheel"/>
    <parent link="link_chassis"/>
    <axis rpy="0 0 0" xyz="0 1 0"/>
    <limit effort="10000" velocity="1000"/>
    <joint_properties damping="1.0" friction="1.0"/>
  </joint>
  
  
</robot>

This file defines the physical parameters of our robot and the type of controller that we want to use.

We’ll create a launch file to launch this description. We name it spawn_urdf.launch and put it under the launch folder.

<?xml version="1.0" encoding="UTF-8"?>
<launch>
    <param name="robot_description" command="cat '$(find my_robot_urdf)/urdf/m2wr.urdf'" />
    
    <node name="mybot_spawn" pkg="gazebo_ros" type="spawn_model" output="screen"
          args="-urdf -param robot_description -model m2wr" />
          
</launch>

You can see that the launch file try to find the description file from the my_robot_urdf package.

Now we have to compile it with the following command

cd ~/catkin_ws
catkin_make
source devel/setup.bash

Now you can launch an empty world simulation from Simulations->Empty, then use the command roslaunch my_robot_urdf spawn_urdf.launch  to spawn the robot!

If you are interested in this topic and want to learn more about URDF, please check our Robot Creation with URDF course.

 

Edit by: Tony Huang

Related resources and links:

Pin It on Pinterest