###### tags: `Tag(ROS,Ubuntu,Python)` # Notedowns for ROS Development ![Robot Operating System](https://i.imgur.com/VZLUgYc.png) ### Table of Content [ToC] ## Usefull commands for ROS * **roscore** : to initialize Ros Master * **catkin_make** : to create a workspace for ROS development. First create a folder named *catkin_ws* and a subfolder named *src*. Then run this command while in *catkinws*. If any program file changes, this function should be called. * **source setup.bash** : After creating catkinws, in the catkin_ws/devel folder call this command on terminal. - In order to avoid doing this everytime we can add this line to setup bash. To do so type on command line: -- **gedit ~/.bashrc** Type at the end of the opening file --**"source ~/catkin_ws/devel/setup.bash"** Save and close. * **catkin_create_pkg [package_name] [dependencies]** : In order to create a package in the catkin_ws/src. rospy will be a dependencies if you want to use python. Or roscpp for C++. In addition std_msgs can be another dependency. -- For ex: ```shell=0 $ catkin_create_pkd my_package roscpp rospy std_msgs ``` * **rosrun [package_name] [node_name]** You can call rosrun from any directory to start your node publishing. One condition: **roscore** must be running. * **rosnode info /[nodeName]** While running [NodeName], you can call info command to observe subsription and publisher features of the related node. This can be used for msg, topic, services etc. * **rosnode ping /[nodeName]** You can ping a node to see it's alive status. * **rosrun rqt_graph rqt_graph** We can run rqt_graph node from rqt_graph package to see running nodes and their relations. * **rosservice call [service_name] [parameters]** For calling a service for debugging on command line * **rostopic echo [topic_name]** For observing a topic on command line * **rosmsg list** Listing all imported message types in MsgPackage/MsgName format * **rosmsg show [MessagePackage]/[MessageName]** ```shell=1 $ rosmsg show rosmsg show std_msgs/Header Output: uint32 seq time stamp string frame_id ``` * **rossrv list** Listing all imported service types in SrvPackage/SrvName format * **rossrv show [ServicePackage]/[ServiceName]** ```shell=1 $ rosmsg show rossrv show std_srvs/SetBool Output: bool data --- bool success string message ``` ## Definitions and Custom Msg/Srv ### **nodes** an executable program running inside the robot application. Processes that perform computation. -- Nodes communicat with each other through topics, services and parameter server -- Nodes reduces code complexity -- Fault tolerance -- Via a node executable, "normally", one can run only one node with same name. However with anonimity feature, one node executable can be used to create multiple nodes with same purpose. ```python= rospy.init_node('nodeName',anonimity = True) ``` ### **packages** collection of nodes for a representative purpose for ex Camera pkg or Motion planning pkg ![Package - Node Relationship](https://i.imgur.com/11DdhZM.png) ### **topics** a named bus which nodes exchange messages -- Topics enables anonimity. Subscriber and publisher don't know each other. Only talk is via topics -- A topic has a message type -- Unidirectional data stream Active topics list: ```shell=1 $ rostopic list ``` Listen a topic: ```shell=2 $ rostopic echo [topicname] ``` Info about a topic : msgType, Publishers, Subscribers etc. ```shell=3 $ rostopic info [topicname] ``` ### **services** specific services for fast response or calculation. A server is reponsible for required computation. A client can request to have the service from the server. More than one client can request from a server. However server should be unique. There is a request-response relationship btw server and client. Active services list: ```shell= $ rosservice list ``` Service call from command line: ```shell= $ rosservice call [service_name] "args" ``` Info about a service ```shell= $ rosservice info [service_name] ``` ### **Creating Custom Messages** * Create new packages for all custom messages: ```shell= $ catkin_create_pkg custom_msgs [dependencies...] ``` * Can delete src and include folder ```shell= $ rm -rf include/, src/ ``` * Edit package.xml and add following lines to the related section (you'll know where :) ```xml= <build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend> ``` * Edit CMakelist.txt and uncomment/edit some sections as below ```xml= generate_messages( DEPENDENCIES std_msgs ) .. .. .. .. .. catkin_package( CATKIN_DEPENDS roscpp rospy std_msgs message_runtime ) ``` * Add subfolder for custom msgs and create a msg ```shell= $ mkdir msg $ cd msg/ $ touch CustomMessage.msg ``` * Customize .msg file, for ex: ```python= int8 param1 string param2 bool param3 ``` * **Important** : For every custom .msg you create do following!Edit CMakelist.txt. Add CustomMessage.msg in this function. ```xml= add_message_files( FILES CustomMessage.msg ) ``` * Finally, call **catkin_make**. * After completing catkin_make do either one: - Call "**source .bashrc**" on terminal - Or open a new terminal (if you do what described at the beginning of the notedown, everytime you open a terminal soruce .bashrc will be called by terminal itself!) * In the catkin_ws/devel/include folder you can see imported custom packages, msgs and services. ```shell= $ cd ~/catkin_ws/devel/include $ ls custom_package1 custom_package2 ... $ cd custom_package1 $ ls CustomMessage1.h CustomService1.h CustomService1Request.h CustomService1Response.h ``` ### Using Custom Messages in a Node/Package * Edit "package.xml" of corresponding Package * Add following line to at the bottom: ```xml= <depend>custom_msgs</depend> ``` ** custom_msgs : your custom msg package* * Now edit CmakeLists.txt. Add custom_msgs to find_package function ```xml= find_package(catkin REQUIRED COMPONENTS roscpp rospy .. .. .. custom_msgs ) ``` ### **Creating Custom Service** * Create a folder in the package which is used to create custom messages * In the package folder, create a folder named "/srv" * Create a .srv file for custom srv ```shell=1 $ touch CustomService.srv ``` * Edit CustomService.srv ```shell=2 $ vim CustomService.srv ``` * In the file, define request and responses. Use "---" btw request and response definitions. **Important!** ```xml= requestType1 request1 requestType2 request2 --- responseType1 response1 ``` * **Save** and close * Go to Package Folder. Edit CMakeLists.txt. * Uncomment *add_service_file()* function and add your custom service inside the function. Everytime you create new custom service, this function should be updated just like custom messages. ```xml=1 add_service_files( FILES CustomService.srv ) ``` * **Save** and close * Go to *catkinws/src* and Run **catkin_make** to build the changes. * **Important** : You need to import the packages you used to create custom server just like in the case of custom messages. If you create new package to do so, follow the steps above for services : [**Using Custom Messages in a Node/Package**](https://hackmd.io/tZ_EaoZOS8O2ci-XEYX8Dw#Using-Custom-Messages-in-a-NodePackage) * After completing catkin_make do either one: - Call "**source .bashrc**" on terminal - Or open a new terminal (if you do what described at the beginning of the notedown, everytime you open a terminal soruce .bashrc will be called by terminal itself!)