Basic Python Nodes to understand essential concepts and the build procedure for a python package.
Link to the README of the
srcfolder here
- Basic Nodes (Python)
- Table of contents
- Creating this package
- Foreword
- Contents
- Nodes
- Simple Hello World
- Simple Publisher
- Simple Subscriber
- Simple Service Server
- Simple Service Client
- Simple Action Server
- Simple Action Client
- Simple Parameter Node
- Launch1 Publisher
- Launch1 Subscriber
- Launch1 Parameters
- Simple Dynamic Reconfiguration Server
- Simple Dynamic Reconfiguration Client
- Simple Module Node
- Basic Math Node
- Services
- Actions
- YAML Files
- Launch Files
- Dynamic Reconfiguration Files
- Reference
This package was creates using the following commands
cd ~/ros_workspaces/learning_ws/src
catkin_create_pkg py_basic_nodes rospyThis is the first package and hence things are described in a little more detail here. The source code has comments describing the contents that are new.
When reading this file, you may either traverse from top to bottom (recommended for beginners) or navigate through table of contents. If you are a beginner, you're suggested to navigate the package using the contents section. In the Nodes section, the nodes are described starting with a table (to lead you to the source code). Same is done for other sections hereon.
Make sure you know how to build a package before proceeding.
Suggested order of traversal for the items in this package (specially for beginners)
| S. No. | Name | Link | Description |
|---|---|---|---|
| 1 | Hello World | Nodes > Simple Hello World | Prints Hello, World! |
| 2 | Publisher (Simple) | Nodes > Simple Publisher | Publish messages |
| 3 | Subscriber (Simple) | Nodes > Simple Subscriber | Subscribe to messages |
| 4 | Creating AddAllFloat64Numbers_py service |
Services > AddAllFloat64Numbers_py | Creating and building your own service (.srv file) |
| 5 | Service Server (Simple) | Nodes > Simple Service Server | Server for the service AddAllFloat64Numbers_py |
| 6 | Service Client (Simple) | Nodes > Simple Service Client | Client for the service AddAllFloat64Numbers_py |
| 7 | Creating CountNumbers_py action |
Actions > CountNumbers_py | Creating and building your own action (.action file) |
| 8 | Action Server (Simple) | Nodes > Simple Action Server | Server for the action CountNumbers_py |
| 9 | Action Client (Simple) | Nodes > Simple Action Client | Client for the action CountNumbers_py |
| 10 | YAML ROS Parameter | YAML Files > Params1 | Simple YAML file which can be loaded on the ROS Parameter Server (.yaml file) |
| 11 | Parameter Node (Simple) | Nodes > Simple Parameter Node | Accessing parameters on the parameter server |
| 12 | Publisher for Launch1 |
Nodes > Launch1 Publisher | A publisher created for a launch file |
| 13 | Subscriber for Launch1 |
Nodes > Launch1 Subscriber | A subscriber created for a launch file |
| 14 | Parameters Node for Launch1 |
Nodes > Launch1 Parameters | Accessing parameters, spawned through a launch file |
| 15 | YAML file 1 for Launch1 |
YAML Files > l1_params1 | A YAML file to load parameters into a launch file |
| 16 | YAML file 2 for Launch1 |
YAML Files > l1_params2 | A YAML file to load parameters into a launch file |
| 17 | Launch1 launch file |
Launch Files > Launch1 | A .launch file to simplify launching everything tagged as Launch1 |
| 18 | FirstDR Dynamic Reconfiguration file |
Dynamic Reconfiguration Files > FirstDR | Creating a .cfg file for parameters that can be dynamically reconfigured |
| 19 | Dynamic Reconfiguration Server (Simple) | Nodes > Simple Dynamic Reconfiguration Server | Creating a server node that will contain the modifiable parameters for dynamic reconfiguration FirstDR |
| 20 | Dynamic Reconfiguration Client (Simple) | Nodes > Simple Dynamic Reconfiguration Client | Creating a client node that will modify parameters of FirstDR on the server |
| 21 | Simple Module Node | Nodes > Simple Module Node | Using simple_module, a Python module belonging to another package |
| 22 | Basic Math Node | Nodes > Basic Math Node | Using basic_math, a more sophisticated module belonging to another package |
Nodes declared in this package
| Field | Value |
|---|---|
| Node name | simple_hello_world_py |
| Code | scripts/simple_hello_world.py |
Node prints Hello, World! and different levels of logging messages.
To create an executable, add the following to the CMakeLists.txt file
- Go to the
Installsection (it must be decorated with "Install" heading)-
Scroll to the
catkin_install_pythonfunctionAdd the following line immediately after the comment block
catkin_install_python(PROGRAMS scripts/simple_hello_world.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )This is necessary to create an executable file for your python script.
More about the
catkin_install_pythonfunction inCMakeLists.txthere and in catkin manual
-
After that, build the package by running catkin_make in the workspace directory. After a successful build process, you must see and executable named simple_hello_world.py in the directory devel/lib/py_basic_nodes (inside the workspace). This means that the workspace stores all the executables in the devel folder.
A similar procedure shall be followed for other nodes, so only the function names shall be mentioned hereon.
First, make sure that roscore is running. To run this node, run
rosrun py_basic_nodes simple_hello_world.pyYou can even locate this package by running
rospack find py_basic_nodesAfter inspecting the output of the following
rosnode listOne can say that the name of the node is what's mentioned in the rospy.init_node function.
Hereon, only the rosrun command (the bare minimum) shall be described.
After that, try running the node as
rosrun py_basic_nodes simple_hello_world.py arg1 arg2 arg3You may kill the node using
rosnode kill /hello_world_simple_pyAfter running the node, a few observations can be made:
- You have successfully run your first Python ROS node.
- The first argument passed to any executable is the full path of the executable, followed by arguments passed during the call.
- Proper logging etiquette is observed. Do not use
printto log things.
| Field | Value |
|---|---|
| Node name | simple_publisher.py |
| Code | scripts/simple_publisher.py |
Node publishes a message on a topic named /simple_py_publisher/hello_str. Demonstrates publishing messages on a topic, name scoping and rate control.
In the CMakeLists.txt, add the following to the catkin_install_python function
scripts/simple_publisher.pybefore the DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}. Then run catkin_make in the workspace folder.
To run the node, run roscore first, then
rosrun py_basic_nodes simple_publisher.pyNow, run
rostopic listYou must see /simple_py_publisher/hello_str in the list. This is because the node was named as such in the Publisher initialization call. If you change "{0}/hello_str".format(rospy.get_name()) to hello_str, the output would have /hello_str instead.
You can inspect the contents of the messages being published by running
rostopic echo /simple_py_publisher/hello_strThis would echo messages from the point where the command was called. You are encouraged to experiment and understand things before proceeding further (same is true for everything hereon).
Kill the nodes using rosnode kill commands.
| Field | Value |
|---|---|
| Node name | simple_py_subscriber |
| Code | scripts/simple_subscriber.py |
Node subscribes to topic named /simple_py_subscriber/subs_str. Demonstrates subscribing to messages received on a topic.
In the CMakeLists.txt, add the following in the catkin_install_python function
scripts/simple_subscriber.pybefore the DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}. Then run catkin_make in the workspace folder.
To run the node, first run roscore, then
rosrun py_basic_nodes simple_subscriber.pyNow, after running
rostopic listYou must see a topic named /simple_py_subscriber/subs_str has been created. Get more information about it using rostopic info.
To publish a message on that topic at a particular frequency, run
rostopic pub /simple_py_subscriber/subs_str std_msgs/String "data: 'Hello World'" -r 0.2This would publish a message with data as Hello World every 5 seconds (0.2 Hz is the rate passed).
You may even experiment with remapping arguments to make the publisher that we had created earlier to publish messages to /simple_py_subscriber/subs_str instead of its default programmed publishing topic /simple_py_publisher/hello_str. To do that, run the following command
rosrun py_basic_nodes simple_publisher.py /simple_py_publisher/hello_str:=/simple_py_subscriber/subs_strRemember that the publisher actually publishes at a programmed rate of 0.5 Hz. If you have the previous rostopic pub node still running, there actually are two nodes publishing and one node subscribing to the topic. Run the following command
rosrun rqt_graph rqt_graphWould produce the following output
You may further experiment with the code to see how the output changes. Most notably, you can do the following
- Try creating a large enough delay in the subscriber callback that messages accumulate. Then see what happens. More about creating a delay in Python here. You can further experiment here with different queue sizes.
| Field | Value |
|---|---|
| Node name | simple_py_service_server |
| Code | scripts/simple_service_server.py |
| Service | AddAllFloat64Numbers_py.srv |
Before this node, you have to understand declaring and building services. Check AddAllFloat64Numbers_py for that. This node demonstrates how to create a service server.
In the CMakeLists.txt, add the following lines at appropriate places
-
Add the script to
catkin_install_pythonfunctionAdd the line
scripts/simple_service_server.py
before the
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}line.
Then, run catkin_make in the workspace folder.
To run this node, run roscore first. To run the node, run
rosrun py_basic_nodes simple_service_server.pyAfter this, the rosservice tool can be used to find if the service is running
rosservice listTo call the service, a service client could be used or the call can also be made through the command line. Try running
rosservice call /simple_py_service_server/add_numbers "data:
- 12.5
- 37.25
- 100.75
- -20.3"When you used tab completion, the first data value would be filled with 0. Just remove the ending " and continue on by typing an enter (or even Ctrl-V Ctrl-J would do). Usually after pressing enter, another prompt shows up to indicate completing the string, that is stored in $PS2 environment variable (usually a >). After pressing enter upon completing the string with ", an output like this must appear
sum: 130.2| Field | Value |
|---|---|
| Node name | simple_py_service_client |
| Code | scripts/simple_service_client.py |
| Service | AddAllFloat64Numbers_py.srv |
Before this node, you have to understand declaring and building services. Check AddAllFloat64Numbers_py for that. This node demonstrates how to create a service client. It will call a service, so the service server needs to be present first. A simple service server is demonstrated above.
In the CMakeLists.txt, add the following lines at appropriate places
-
Add the script to
catkin_install_pythonfunctionAdd the line
scripts/simple_service_client.py
before the
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}line.
Then, run catkin_make in the workspace folder.
To run this node, run roscore first. To use this node, a service server (servicing the service mentioned in the node, that is bearing the name /simple_py_service_server/add_numbers) must be running. This package has the corresponding service server node. To run that node, run
rosrun py_basic_nodes simple_service_server.pyEnsure that the service /simple_py_service_server/add_numbers is running (using rosservice list)
To run this node, run a command like what's shown below (you can use any numbers in the argument)
rosrun py_basic_nodes simple_service_client.py 60 4 0.5 -98.7If everything's gone right, the sum must return -34.2 for the given numbers.
| Field | Value |
|---|---|
| Node name | simple_py_action_server |
| Code | scripts/simple_action_server.py |
| Action | action/CountNumbers_py.action |
Before this node, you have to understand how .action files are build, check Actions > CountNumbers_py for that. This node shows how to create an action server.
In the CMakeLists.txt file, add the following line in catkin_install_python function before the DESTINATION line
scripts/simple_action_server.pyThen, run catkin_make in the workspace
To run this node, run roscore first. To run the node, run
rosrun py_basic_nodes simple_action_server.pyNote that actions actually use messages to communicate. To see the messages for the action, run the following command
rostopic list | grep /simple_py_action_server/count_numbers/You'll see messages for cancel, feedback, goal, result and status. To test and see how the actionlib mechanism may work, run these commands in separate terminals that you can see at the same time
rostopic echo /simple_py_action_server/count_numbers/result
rostopic echo /simple_py_action_server/count_numbers/feedback
rostopic echo /simple_py_action_server/count_numbers/statusThen, in another terminal, we will publish a message to the goal topic. You could use the command below
rostopic pub /simple_py_action_server/count_numbers/goal py_basic_nodes/CountNumbers_pyActionGoal "header:
seq: 0
stamp:
secs: 0
nsecs: 0
frame_id: ''
goal_id:
stamp:
secs: 0
nsecs: 0
id: ''
goal:
target_number: 15
del_ms: 500" -1The above command will tell the server to count up to 15 with a delay of 500 ms between each count. After everything is done, the output must look somewhat like below
The status is being displayed on the bottom right, with the feedback on top and result left to it. The main node is at the top left and under it is the publisher to goal.
As seen in the code, we have only programmed the logic of execution, and everything on the communication side has been handled by the actionlib package (which is why we needed it as a dependency). However, the method that we used here is not a proper one used to call actions (notice that we did not fill many fields in the goal publisher command above, namely header and goal ID). For that, we need to create an action client. Then, actionlib would handle the publishing part as well, we'd only have to give it the goal.
| Field | Value |
|---|---|
| Name | simple_py_action_client |
| Code | scripts/simple_action_client.py |
| Action | action/CountNumbers_py.action |
Before this node, you have to understand how .action files are build, check Actions > CountNumbers_py for that. This node shows how to create an action client. A simple action server that can be used with this client is demonstrated above.
In the CMakeLists.txt file, add the following line in catkin_install_python function before the DESTINATION line
scripts/simple_action_client.pyThen, run catkin_make in the workspace folder
To run this node, run roscore first. In order to run an action client, an action server has to be spawned first, run the following
rosrun py_basic_nodes simple_action_server.pyNow, you can run the client using (run this on a different terminal window)
rosrun py_basic_nodes simple_action_client.py 10 500This must produce the following output
You are encouraged to inspect the contents of the underlying messages as discussed in the simple action server.
| Field | Value |
|---|---|
| Name | simple_py_parameter_node |
| Code | scripts/simple_parameter_server.py |
Before this, it is suggested that you get a hands on experience with parameters. You must also understand the notion of storing and loading parameters through YAML files. Check out YAML Files > Params for understanding YAML files and parameter server in ROS.
In the CMakeLists.txt file, add the following line in catkin_install_python function before the DESTINATION line
scripts/simple_parameter_server.pyThen, run catkin_make in the workspace folder
First, run roscore, then run this node using
rosrun py_basic_nodes simple_parameter_server.pyThe output must consist of the contents of existing parameters (some keys/parameters may not be found and that's okay, you can roskill the node now). It must also have created another parameter on the server by the name of /custom_py_parameter, check it using rosparam get (this will persist even after the node as the resource is on the ROS Master). You must now load the Params1.yaml file into the parameter server and then rerun the node.
rosparam load `rospack find py_basic_nodes`/yaml/Params1.yaml
rosrun py_basic_nodes simple_parameter_server.pyNow, the node must display the values of the parameters on the parameter server having previously unidentified keys. Most importantly, a junk parameter with the key junk_parameter must have been loaded by the YAML file (through rosparam load command) and then deleted by this node (check using rosparam list before running the node and after running the node, with the YAML file freshly loaded this time).
| Field | Value |
|---|---|
| Node name | launch1_publisher |
| Code | scripts/launch1_publisher.py |
| Launch File | launch/launch1.launch |
A publisher made for the purpose of Launch1 file. Simply publishes messages to the topic pub_topic. Also uses a local parameter called ~/l1pub_PubFreq to set the frequency of publishing (see code for more information).
In the CMakeLists.txt file, add the following line in catkin_install_python function before the DESTINATION line
scripts/launch1_publisher.pyThen, run catkin_make in the workspace folder. This node, along with some others, is supposed to be run in the launch1.launch process (check it out here).
| Field | Value |
|---|---|
| Node name | launch1_subscriber |
| Code | scripts/launch1_subscriber.py |
| Launch File | launch/launch1.launch |
A subscriber made for the purpose of Launch1 file. Simply subscribes to messages on topic subs_topic (see code for more information).
In the CMakeLists.txt file, add the following line in catkin_install_python function before the DESTINATION line
scripts/launch1_subscriber.pyThen, run catkin_make in the workspace folder. This node, along with some others, is supposed to be run in the launch1.launch process (check it out here).
| Field | Value |
|---|---|
| Name | launch1_params |
| Code | scripts/launch1_parameters.py |
| Launch File | launch/launch1.launch |
A node made to print out all parameter keys. It is suggested that you see l1_params1 and l1_params2 .yaml parameter files.
In the CMakeLists.txt file, add the following line in catkin_install_python function before the DESTINATION line
scripts/launch1_parameters.pyThen, run catkin_make in the workspace folder. This node, along with some others, is supposed to be run in the launch1.launch process (check it out here).
| Field | Value |
|---|---|
| Name | simple_py_firstdr_server |
| File | scripts/simple_FirstDR_server.py |
| Dynamic Reconfiguration File | cfg/FirstDR.cfg |
A dynamic reconfiguration server made to host the parameters included in the .cfg file. This node depends on the dynamic reconfiguration file. A server maintains the record of parameters and provides a callback interface for handling updates (these updates are made by a client). A client is implemented in this package
In the CMakeLists.txt file, add the following line in catkin_install_python function before the DESTINATION line
scripts/simple_FirstDR_server.pyThen, run catkin_make in the workspace folder.
First, run roscore, then run this node using
rosrun py_basic_nodes simple_FirstDR_server.pyThe output will consist of the default parameters being loaded in the callback (with level being -1 as no signal was called). The node then goes into spinning mode.
To call the callback, you'll need a client. You could create a node for that, however a simple GUI client is available using rqt_reconfigure. To run it, run
rosrun rqt_reconfigure rqt_reconfigureThis should open a GUI window like whats shown below
You can modify the values and see the output in the terminal running the node. You can also save the modified parameters as a .yaml file and restore them. This shall also allow testing how multiple parameters can be changed in just one attempt.
For example, for the following rqt_reconfigure configurations
The result is the following
Notice the level passed, it is the binary OR of all the parameters with a different value. You may also verify that the parameters are actual parameters on the ROS Parameter Server by inspecting the output of rosparam list. You may also what to check the /simple_py_firstdr_server/set_parameters service.
| Field | Value |
|---|---|
| Name | simple_py_firstdr_server |
| File | scripts/simple_FirstDR_client.py |
| Dynamic Reconfiguration File | cfg/FirstDR.cfg |
A dynamic reconfiguration client made to modify parameters on a dynamic reconfiguration server. The parameters are included in the specified .cfg dynamic reconfiguration file. A client sends commands to the server (which maintains a service to handle changes in parameters). A simple server is implemented in this package.
In the CMakeLists.txt file, add the following line in catkin_install_python function before the DESTINATION line
scripts/simple_FirstDR_client.pyThen, run catkin_make in the workspace folder.
First, run roscore. Before running this node, you need the simple_FirstDR_server.py node running (because it serves as the server for this node, check the code). To run it, use this command
rosrun py_basic_nodes simple_FirstDR_server.pyThen, run this node using
rosrun py_basic_nodes simple_FirstDR_client.pyThe output on this node screen may be the following
The output on the server node may be the following
You may check the service /simple_py_firstdr_server/set_parameters and may also see the output of rosrun rqt_graph rqt_graph. What may be more interesting is that running rosrun rqt_reconfigure rqt_reconfigure opens the same GUI window as it did earlier in the case of server, but it also shows the updates in parameters in real time. This synchronization is handled in the background by the dynamic_reconfigure package.
| Field | Value |
|---|---|
| Name | simple_module_node |
| File | scripts/simple_module_node.py |
| Module | simple_module |
This node simply includes the functionality of the simple_module python module. Before understanding this, you might want to understand the basic_py_libs package (up to the definition of this module).
Add the dependency on basic_py_libs by
- Adding the
<depend>basic_py_libs</depend>line inpackage.xml - Adding
basic_py_libsin thefind_package(catkin REQUIRED COMPONENTS ...list
To install the script, add the scripts/simple_module_node.py file to the catkin_install_python function in CMakeLists.txt. Then, run catkin_make in the workspace directory. To run this node, ensure that roscore is running first and then run
rosrun basic_py_libs simple_module_node.py| Field | Value |
|---|---|
| Name | basic_math_node |
| File | scripts/basic_math_node.py |
| Module | basic_math |
This node simply demonstrates how to access functionality of the basic_math python module. Before understanding this, you might want to understand the basic_py_libs package (up to the definition of this module).
Add the dependency on basic_py_libs by
- Adding the
<depend>basic_py_libs</depend>line inpackage.xml - Adding
basic_py_libsin thefind_package(catkin REQUIRED COMPONENTS ...list
To install the script, add the script script/basic_math_node.py to catkin_install_python function in CMakeLists.txt and run catkin_make in the workspace directory. To run this node, first run roscore and then run
rosrun basic_py_libs basic_math_node.pyServices declared in this package
| Field | Value |
|---|---|
| Name | AddAllFloat64Numbers_py |
| File | srv/AddAllFloat64Numbers_py.srv |
| Service Request | float64[] data |
| Service Response | float64 sum |
A service that adds all the numbers sent in the request and sends the result as a response. For example, if we send 1, -2.3, 56, -4 in request, it will send 50.7 (their sum) in response. However, note that the logic is not in the .srv file, but in the service server. This file only describes the structure.
The file description is actually just created a service description file. We need to build the files (header and source files) so that this and other packages can use this service.
To do that, open package.xml file and add the following lines at appropriate places:
-
Add a
build_dependtomessage_generation. This will allow building messages, services and actions at compile time.Go to the part where
<build_depend>tags are located and add the following tags to the list<build_depend>message_generation</build_depend> <build_depend>std_msgs</build_depend>
This would tell that the package depends on
message_generationpackage for building. The packagemessage_generationis used for building the messages, services and actions. The second package,std_msgs, is needed for the messages. -
Add an
exec_dependtomessage_runtime.Go to the part where
<exec_depend>tags are located and add the following tag to the list<exec_depend>message_runtime</exec_depend> <exec_depend>std_msgs</exec_depend>
This is used to tell that we need the
message_runtimepackage at runtime. The second package,std_msgs, is needed for the messages.
As the package.xml file is just a manifesto file, we need to make the following changes to the CMakeLists.txt file (as that is the file which is used to actually build the package)
-
In the
find_packagefunction, addmessage_generationtocatkin REQUIRED COMPONENTSin a new line (after the end of already declared packages)After adding
message_generation(and addingstd_msgsfor standard messages), the function must look somewhat like thisfind_package(catkin REQUIRED COMPONENTS rospy message_generation std_msgs )
More about the
find_packagefunction here -
Under
catkin specific configurationheading (just before theBuildheading), addmessage_runtimeasCATKIN_DEPENDS.After adding
message_runtime(andstd_msgsfor standard messages), the function must look somewhat like thiscatkin_package( # INCLUDE_DIRS include # LIBRARIES py_basic_nodes CATKIN_DEPENDS rospy message_runtime std_msgs # DEPENDS system_lib )
More about the
catkin_packagefunction here -
Go to the
Declare ROS messages, services and actionsheading. You shall also find the whole procedure as comments in this section.-
Add the
add_action_files(you could uncomment the existing code, or write a new one under it).Include the
.srvfiles declared in thesrvfolder here. After adding the function, it would look like thisadd_service_files( FILES AddAllFloat64Numbers_py.srv ) -
Add the
generate_messagesfunction to the macro. This is to invoke code generation for the source code.Add the
std_msgsdependency. After everything, the function must look like thisgenerate_messages( DEPENDENCIES std_msgs # Float64 )
There is an example on roswiki to demonstrate changes to the CMakeLists.txt file for adding custom messages, services and actions
-
After this, run catkin_make in the workspace directory.
After a successful build, the python modules (that can be imported) can be found in the devel/lib/python3/dist-packages directory inside the workspace directory. It must be inside a folder named py_basic_nodes. Within this folder, you must find a srv folder (which is a common folder for all services generated by the package).
You can also see the header files for C++ generated in the devel/include folder inside the workspace folder. These header files can be included in nodes programmed using C++.
For any IDE, you may want to include the devel/lib/python3/dist-packages directory (for auto completion features).
Actions declared in this package
| Field | Value |
|---|---|
| Name | CountNumbers_py |
| File | action/CountNumbers_py.action |
| Goal | uint32 target_number; uint32 del_ms |
| Result | string res_note |
| Feedback | uint32 curr_number |
An action that counts the numbers up to a requested number. For example, if the goal is to count up to 5 (target_number) with a delay of 1000 (del_ms), then in feedback, the node will send numbers 1, 2, 3, 4, 5 and then send the result as Done (or something similar). Note that the .action file only describes the structure of the action. The logic is defined in the action server implementation and not in the .action file.
The file is actually just an action description file. We need to build the files (header and source files) so that this and other packages can use this service. Its suggested that you see the building process of services first.
To do that, open package.xml file and add the following lines at appropriate places:
-
Add a
dependtoactionlibandactionlib_msgs. This will allow us to build the actions.Add these lines before the
exectags (just a convention)<depend>actionlib</depend> <depend>actionlib_msgs</depend>
This would tell that the package depends on
actionlibandactionlib_msgsduring build and execution times.
Add the following at appropriate places
-
In the
find_packagefunction, addactionlib,genmsgandactionlib_msgstocatkin REQUIRED COMPONENTSin a new line (after the end of already declared packages)The function must look somewhat like this
find_package(catkin REQUIRED COMPONENTS rospy message_generation std_msgs actionlib genmsg actionlib_msgs )The
genmsgpackage is to generate messages out of the.actionfile. Messages are generated for Goal, Result and Feedback. Packagemessage_generationis not required (it is from the services section). -
Go to the
Declare ROS messages, services and actionsheading.-
Add the
add_action_filesfunctionInclude the
.actionfiles declared in theactionfolder here. After adding the function, it would look like thisadd_action_files( FILES CountNumbers_py.action ) -
Add the
generate_messagesfunction.Add the
actionlib_msgsdependency. After everything, the function must look like thisgenerate_messages( DEPENDENCIES std_msgs # Float64 actionlib_msgs )The
std_msgsis not necessary (it is for the services in the package). -
Add
actionlib_msgsto thecatkin_packagefunction as aCATKIN_DEPENDSpackageAfter adding it, the function may look somewhat like this
catkin_package( # INCLUDE_DIRS include # LIBRARIES py_basic_nodes CATKIN_DEPENDS rospy message_runtime std_msgs actionlib_msgs # DEPENDS system_lib )
The
std_msgsis not necessary (it is for the services in the package).
There is an example on roswiki to demonstrate a sample
.actionfile and building it. -
After all that, run catkin_make in the ros workspace directory. After a successful build, the libraries for Python nodes must be available in devel/lib/python3/dist-packages/py_basic_nodes directory of the workspace (C++ libraries are in the devel/include/py_basic_nodes directory). You can see the messages created by running the command
rosmsg list | grep py_basic_nodes/CountNumbers_pyThere will be messages for actions as well as individual messages for the goal, feedback and result.
| Field | Value |
|---|---|
| Name | Params1 |
| File | yaml/Params1.yaml |
This file contains parameters that can be loaded to the ROS Master (on the Parameter Server).
Make sure the master is running first
roscoreWe use the rosparam tool to list, get and load parameters from a YAML file. Now let's list the parameters that are present when roscore is launched.
rosparam listSay we want to get the value of /run_id, use rosparam get
rosparam get /run_idYou can save all the current parameters in a temporary file
rosparam dump curr_params.yamlThe contents of the file are the parameters in the ROS Parameter Server. To load the parameters in this file (Params1.yaml) into the ROS parameter server, run the following command
rosparam load `rospack find py_basic_nodes`/yaml/Params1.yamlThe rospack find py_basic_nodes command is to find this package (named py_basic_nodes), and then point to the YAML file from which parameters have to be loaded. You can view individual parameters using rosparam get or dump it into another file.
| Field | Value |
|---|---|
| Name | l1_params1 |
| File | yaml/l1_params1.yaml |
This file is to load some parameters for launch1. Note that the cat command is used to pipe the contents to the <param> in the launch file.
| Field | Value |
|---|---|
| Name | l1_params2 |
| File | yaml/l1_params2.yaml |
This file is to load some parameters for launch1. This file contains parameters intended for global scope / usage. Note that the cat command is used to pipe the contents to the <param> in the launch file.
| Field | Value |
|---|---|
| Name | launch1 |
| File | launch/launch1.launch |
A launch file is used to execute multiple nodes and run multiple commands in one go, so that you do not have to keep opening new terminals and typing new commands every time. Check out the file to know more.
In order to run this file, use the following command
roslaunch py_basic_nodes launch1.launchAfter launching, the following nodes must have spawned (use rosnode list to get these):
/rqt_console: This is a console to visualize the messages being transmitted (since the output is logged, although there also is provision to log to the screen but it is less preferred as it would produce too much clutter). Experiment with the console (exclude and highlight messages)./l1/ps/pyl1_publisher: This is the publisher node (note the namespace and renaming)./l1/ps/pyl1_subscriber: This is the subscriber node./l1/params/pyl1_parameters: This is the parameter keys node.
The following topics are of importance (use rostopic list to get these):
/l1/ps/topic: The topic to which the publisher publishes and subscriber subscribes. Note that this is completely achieved through argument remapping and namespace allocation (because the nodes themselves use a different topic by default).
You must observe the parameters present by running rosparam list. The following are important observations:
/global/*are parameters in the global declaration/l1/params/set1/*are parameters in the group declaration/l1/ps/pyl1_publisher/l1pub_PubFreqis a private parameter but still shared with the parameter server
Also note that upon closing the rqt_console window, the launch closes. This is because of the required attribute in the <node> for it.
After closing the launch, it is possible to see all the output generated by the nodes. This is available in the directory ~/.ros/log/latest (by default). Each file will contain the output generated by the particular node.
About: Dynamic Reconfiguration is used to create parameters that can be updated at runtime. This is done using a client and server model (very similar to that of services), but here the server hosts and stores the parameters and the client is used to modify them. A
.cfgfile outlines the details about the parameter (kind of like how.msgfiles define a message, or.srvfiles define a service).
Dynamic Reconfiguration Files in this package
| Field | Value |
|---|---|
| Name | FirstDR |
| File | cfg/FirstDR.cfg |
Holds the following dynamic reconfigurations as template
| Parameter Name | Type | Description | Default Value |
|---|---|---|---|
| user_int | int_t |
A configurable integer | 50 |
| usr_int1 | int_t |
An integer with level 3 | 50 |
| usr_int2 | int_t |
An integer with level 2 | 50 |
| usr_int3 | int_t |
An integer with level 8 | 50 |
| user_bool | bool_t |
A boolean value | False |
| user_str | str_t |
A string value | "Hello, World!" |
To build a dynamic reconfiguration file, you have to first add dependency to a package called dynamic_reconfigure. This package contains all code to build the files.
-
Add the following lines to
Package.xmlfile at the appropriate placesYou will need build time and run time dependency on
dynamic_reconfigure<build_depend>dynamic_reconfigure</build_depend> <exec_depend>dynamic_reconfigure</exec_depend>
-
Open
CMakeLists.txtand adddynamic_reconfigureto the list of packages in thefind_package(catkin REQUIRED COMPONENTS ...)function. -
You have to now define the particular
.cfgfiles in your package. There is a section inCMakeLists.txtfile to define those. Scroll down to a section labelledDeclare ROS dynamic reconfigure parameters.Add the function
generate_dynamic_reconfigure_optionsto the file (either uncomment or add below).generate_dynamic_reconfigure_options( cfg/FirstDR.cfg )The parameter passed (
cfg/FirstDR.cfghere) is the path of the.cfgfile in the package. Usually, these files are stored in a folder namedcfg(just as there are dedicated folders for service files, calledsrv).
After this, run catkin_make in the workspace directory. Wait till build is completed.
Go to the directory devel/lib/python3/dist-packages/py_basic_nodes/cfg in the workspace. Here you'll find the python modules generated for the file (here, it will be FirstDRConfig.py). If you're interested in headers for C++, they're stored in devel/include/py_basic_nodes directory in the workspace (named FirstDRConfig.h).
- roswiki







