# ROS Notes
[](https://hackmd.io/J4AIczR0THGBRFAYlGlpOA)
Refer for Linux
http://www.ee.surrey.ac.uk/Teaching/Unix
- A good way to check is to ensure that environment variables like ROS_ROOT and ROS_PACKAGE_PATH are set:
> printenv | grep ROS
- Rosbuild and Catkin are the two available methods for organizing and building your ROS code.
- If you just installed ROS from apt on Ubuntu then you will have setup.*sh files in '/opt/ros/<distro>/', and you could source them like so:
> source /opt/ros/<distro>/setup.bash
- You will need to run this command on every new shell you open to have access to the ROS commands, unless you add above line to your .bashrc. This process allows you to install several ROS distributions (e.g. indigo and kinetic) on the same computer and switch between them.
- The catkin_make command is a convenience tool for working with catkin workspaces
- To make sure your workspace is properly overlayed by the setup script, make sure ROS_PACKAGE_PATH environment variable includes the directory you're in.
> echo $ROS_PACKAGE_PATH
##### Filesytem Concepts:
- Packages: Packages are the software organization unit of ROS code. Each package can contain libraries, executables, scripts, or other artifacts.
- Manifests (package.xml): A manifest is a description of a package. It serves to define dependencies between packages and to capture meta information about the package like version, maintainer, license, etc...
##### Using rospack
- rospack allows you to get information about packages.
> rospack find [package_name]
###### roscd
- roscd is part of the rosbash suite. It allows you to change directory (cd) directly to a package or a stack.
- roscd can also move to a subdirectory of a package or stack.
> roscd [locationname[/subdir]]
- roscd log will take you to the folder where ROS stores log files
> roscd log
###### rosls
- rosls is part of the rosbash suite. It allows you to ls directly in a package by name rather than by absolute path.
> rosls [locationname[/subdir]]
##### What makes up a catkin Package?
For a package to be considered a catkin package it must meet a few requirements:
- The package must contain a catkin compliant package.xml file. That package.xml file provides meta information about the package.
- The package must contain a CMakeLists.txt which uses catkin. If it is a catkin metapackage it must have the relevant boilerplate CMakeLists.txt file.
- Each package must have its own folder
This means no nested packages nor multiple packages sharing the same directory.
###### Create Catkin Package
- Use the catkin_create_pkg script to create a new package called 'beginner_tutorials' which depends on std_msgs, roscpp, and rospy:
- catkin_create_pkg requires that you give it a package_name and optionally a list of dependencies on which that package depends:
> catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
> catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
###### Building package
- Need to build the packages in the catkin workspace. catkin_make is a command line tool which adds some convenience to the standard catkin workflow. You can imagine that catkin_make combines the calls to cmake and make in the standard CMake workflow.
> catkin_make
- After the workspace has been built it has created a similar structure in the devel subfolder as you usually find under /opt/ros/$ROSDISTRO_NAME
**To add the workspace to your ROS environment you need to source the generated setup file**
> . ~/catkin_ws/devel/setup.bash
###### Package dependencies
- When using catkin_create_pkg earlier, a few package dependencies were provided. These first-order dependencies can now be reviewed with the rospack tool.
> rospack depends1 beginner_tutorials
###### Graph concepts
- Nodes: A node is an executable that uses ROS to communicate with other nodes. node really isn't much more than an executable file within a ROS package. ROS nodes use a ROS client library to communicate with other nodes. Nodes can publish or subscribe to a Topic. Nodes can also provide or use a Service.
- Messages: ROS data type used when subscribing or publishing to a topic.
- Topics: Nodes can publish messages to a topic as well as subscribe to a topic to receive messages.
- Master: Name service for ROS (i.e. helps nodes find each other)
- rosout: ROS equivalent of stdout/stderr
- roscore: Master + rosout + parameter server
###### Client Libraries
- rospy = python client library
- roscpp = c++ client library
##### If roscore does not initialize and sends a message about lack of permissions, probably the ~/.ros folder is owned by root, change recursively the ownership of that folder with:
> sudo chown -R <your_username> ~/.ros
###### Using Rosnode
- rosnode displays information about the ROS nodes that are currently running. The rosnode list command lists these active nodes
> rosnode list
- *rosout* is always running as it collects and logs nodes' debugging output.
- The rosnode info command returns information about a specific node.
> rosnode info /rosout
###### Using rosrun
- rosrun allows you to use the package name to directly run a node within a package (without having to know the package path).
> rosrun [package_name] [node_name]
> rosnode list
- To change the node's name use Remapping Argument
> rosrun turtlesim turtlesim_node __name:=my_turtle
- If you see \turtlesim, try cleaning the rosnode list with
> rosnode cleanup
- To test the current node is up use
> rosnode ping my_turtle
##### ROS Topics
###### turtle keyboard teleoperation
- Need something to drive the turtle around with, use
> rosrun turtlesim turtle_teleop_key
###### Using rqt_graph
- Use rqt_graph, which shows the nodes and topics currently running. rqt_graph creates a dynamic graph of what's going on in the system. rqt_graph is part of the rqt package
> rosrun rqt_graph rqt_graph
- The rostopic tool allows you to get information about ROS topics.
You can use the help option to get the available sub-commands for rostopic
> rostopic -h
- rostopic echo shows the data published on a topic.
> rostopic echo [topic]
- Using rostopic list: rostopic list returns a list of all topics currently subscribed to and published.
> rostopic list -h
- For rostopic list use the verbose option:
>rostopic list -v
##### ROS Messages
- Communication on topics happens by sending ROS messages between nodes. For the publisher (turtle_teleop_key) and subscriber (turtlesim_node) to communicate, the publisher and subscriber must send and receive the same type of message. This means that a topic type is defined by the message type published on it. The type of the message sent on a topic can be determined using rostopic type.
- rostopic type returns the message type of any topic being published.
> rostopic type [topic]
- We can look at the details of the message using rosmsg:
> rosmsg show geometry_msgs/Twist
- rostopic pub publishes data on to a topic currently advertised.
> rostopic pub [topic] [msg_type] [args]
- This option (dash-one) causes rostopic to only publish one message then exit
- This option (double-dash) tells the option parser that none of the following arguments is an option. This is required in cases where your arguments have a leading dash -, like negative numbers.
- We can publish a steady stream of commands using *rostopic pub -r* command.
- rostopic hz reports the rate at which data is published
> rostopic hz [topic]
- Now that the turtlesim is publishing data about our turtle at the rate of 60 Hz. We can also use rostopic type in conjunction with rosmsg show to get in depth information about a topic
> rostopic type /turtle1/cmd_vel | rosmsg show
##### ROS Services
Services are another way that nodes can communicate with each other. Services allow nodes to send a request and receive a response
- rosservice can easily attach to ROS's client/service framework with services. rosservice has many commands that can be used on services.
- The list command shows us that the turtlesim node provides nine services
> rosservice list
- rosservice type
> rosservice type [service]
- rosservice call
> rosservice call [service] [args]
###### Using rosparam
rosparam allows you to store and manipulate data on the ROS Parameter Server. The Parameter Server can store integers, floats, boolean, dictionaries, and lists. rosparam uses the YAML markup language for syntax
- rosparam list
> rosparam list
- rosparam set and rosparam get
>rosparam set [param_name]
> rosparam get [param_name]
- rosparam dump and rosparam load
> rosparam dump [file_name] [namespace]
>rosparam load [file_name] [namespace]
##### Using rqt_console and rqt_logger_level
- rqt_console attaches to ROS's logging framework to display output from nodes. rqt_logger_level allows us to change the verbosity level (DEBUG, WARN, INFO, and ERROR) of nodes as they run.
>rosrun rqt_console rqt_console
>rosrun rqt_logger_level rqt_logger_level
- Fatal has the highest priority and Debug has the lowest. By setting the logger level, you will get all messages of that priority level or higher.
###### Using roslaunch
- roslaunch starts nodes as defined in a launch file.
> roslaunch [package] [filename.launch]
###### Using rosed
- rosed is part of the rosbash suite. It allows you to directly edit a file within a package by using the package name rather than having to type the entire path to the package.
> rosed [package_name] [filename]
##### ROS msg and srv
- *msg*: msg files are simple text files that describe the fields of a ROS message. They are used to generate source code for messages in different languages.
- *srv*: an srv file describes a service. It is composed of two parts: a request and a response.
- msg files are stored in the msg directory of a package, and srv files are stored in the srv directory.
- There is also a special type in ROS: Header, the header contains a timestamp and coordinate frame information that are commonly used in ROS. You will frequently see the first line in a msg file have Header header.
- srv files are just like msg files, except they contain two parts: a request and a response.
###### Creating a msg
- create a .msg file and add your data into it (add field type and field name)
> echo "int64 num" > msg/Num.msg
- To make sure that the msg files are turned into source code for C++, Python, and other languages for that
- Open package.xml, and make sure required lines are in it and uncommented:
- Open CMakeLists.txt and add dependency to the *find_package* call which already exists in your CMakeLists.txt so that can generate messages
- By adding the .msg files manually, make sure that CMake knows when it has to reconfigure the project after you add other .msg files.
###### Using rosmsg
- Make sure that ROS can see it using the rosmsg show command by
> rosmsg show [message type]
- If you can't remember which Package a msg is in, you can leave out the package name. Try:
> rosmsg show Num(msg name)
###### Creating a srv
- to create a srv:
> roscd beginner_tutorials
> mkdir srv
- *roscp* is a useful commandline tool for copying files from one package to another.
> roscp [package_name] [file_to_copy_path] [copy_path]
- There's one more step, though. We need to make sure that the srv files are turned into source code for C++, Python, and other languages for that,
- open package.xml, and make sure required lines are in it and uncommented
- replace the placeholder Service*.srv files for your service files:
- Make sure that ROS can see it using the rossrv show command.
> rossrv show <service type>
- Any .msg file in the msg directory will generate code for use in all supported languages. The C++ message header file will be generated in ~/catkin_ws/devel/include/beginner_tutorials/. The Python script will be created in ~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg. The lisp file appears in ~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/.
##### Writing the Publisher Node
- "Node" is the ROS term for an executable that is connected to the ROS network. Here created a publisher ("talker") node which will continually broadcast a message.
In the Publisher node:
- The **ros::init()** function needs to see argc and argv so that it can perform any ROS arguments and name remapping that were provided at the command line. The third argument to init() is the name of the node.
- *NodeHandle* is the main access point to communications with the ROS system. The first NodeHandle constructed will fully initialize this node, and the last NodeHandle destructed will close down the node.
- The *advertise()* function is how you tell ROS that you want to publish on a given topic name.
- After this advertise() call is made, the master node will notify anyone who is trying to subscribe to this topic name, and they will in turn negotiate a peer-to-peer connection with this node. advertise() returns a Publisher object which allows you to publish messages on that topic through a call to publish(). Once all copies of the returned Publisher object are destroyed, the topic will be automatically unadvertised.
- The second parameter to advertise() is the size of the message queue used for publishing messages.
- The publish() function is how you send messages. The parameter is the message object. The type of this object must agree with the type given as a template parameter to the *advertise<>()* call.
##### Writing the Subscriber Node
- In subsciber node:
- The **ros::init()** function needs to see argc and argv so that it can perform any ROS arguments and name remapping that were provided at the command line. For programmatic remappings you can use a different version of init() which takes remappings directly, but for most command-line programs, passing argc and argv is the easiest way to do it. The third argument to init() is the name of the node.
- The *subscribe()* call is how you tell ROS that you want to receive messages on a given topic. This invokes a call to the ROS master node, which keeps a registry of who is publishing and who is subscribing. Messages are passed to a callback function, here called chatterCallback. subscribe() returns a Subscriber object that you must hold on to until you want to unsubscribe. When all copies of the Subscriber object go out of scope, this callback will automatically be unsubscribed from this topic.
- The second parameter to the subscribe() function is the size of the message queue.
##### Python Subsciber/Publisher Node
- Every Python ROS Node will have this declaration at the top. The first line makes sure your script is executed as a Python script.
> #!/usr/bin/env python
- The next line, *rospy.init_node(NAME, ...)*, is very important as it tells rospy the name of your node -- until rospy has this information, it cannot start communicating with the ROS Master. In this case, your node will take on the name talker.
- *anonymous = True* ensures that your node has a unique name by adding random numbers to the end of NAME
- loop also calls *rospy.loginfo(str)*, which performs triple-duty: the messages get printed to screen, it gets written to the Node's log file, and it gets written to rosout. rosout is a handy tool for debugging: you can pull up messages using rqt_console instead of having to find the console window with your Node's output.
- In addition to the standard Python __main__ check, this catches a rospy.ROSInterruptException exception, which can be thrown by rospy.sleep() and rospy.Rate.sleep() methods when Ctrl-C is pressed or your Node is otherwise shutdown. The reason this exception is raised is so that you don't accidentally continue executing code after the sleep().
> try:
> talker()
> except rospy.ROSInterruptException:
> pass
- Unlike roscpp, *rospy.spin()* does not affect the subscriber callback functions, as those have their own threads.
###### Running the Publisher and Subscriber
- If you are using catkin, make sure you have sourced your workspace's setup.sh file after calling catkin_make but before trying to use your applications
> (In your catkin workspace)
> cd ~/catkin_ws
> source ./devel/setup.bash
- for running Publisher and Subscribe
> rosrun beginner_tutorials talker.py (python)
> rosrun beginner_tutorials talker (c++)
> rosrun beginner_tutorials listener (c++)
> rosrun beginner_tutorials listener.py (Python)
##### Recording and playing back data
###### Recording data (creating a bag file)
- To record topic data from a running ROS system, the topic data will be accumulated in a bag file.
- The list of published topics are the only message types that could potentially be recorded in the data log file, as only published messages are recorded.
> mkdir ~/bagfiles
> cd ~/bagfiles
> rosbag record -a
- Here we are just making a temporary directory to record data and then running **rosbag record** with the option -a, indicating that all published topics should be accumulated in a bag file.
###### Examining and playing the bag file
- Now recorded a bag file using rosbag record we can examine it and play it back using the commands **rosbag info** and **rosbag play**.
- *info* command -- this command checks the contents of the bag file without playing it back
> rosbag info <your bagfile>
- This tells us topic names and types as well as the number (count) of each message topic contained in the bag file.
- In its default mode rosbag play will wait for a certain period (.2 seconds) after advertising each message before it actually begins publishing the contents of the bag file.
> rosbag play <your bagfile>
- If rosbag play publishes messages immediately upon advertising, subscribers may not receive the first several published messages. The waiting period can be specified with the -d option.
- You can have rosbag play not start at the beginning of the bag file but instead start some duration past the beginning using the -s argument. A final option that may be of interest is the -r option, which allows you to change the rate of publishing by a specified factor
> rosbag play -r 2 <your bagfile>
###### Recording a subset of the data
- The rosbag record command supports logging only particular topics to a bag file, allowing users to only record the topics of interest to them.
> rosbag record -O subset /turtle1/cmd_vel /turtle1/pose
- The -O argument tells rosbag record to log to a file named subset.bag, and the topic arguments cause rosbag record to only subscribe to these two topics.
###### Reading messages from a bag file
- You need to know the exact topic names you'd like to read from the bag file. So, let's see what's in the bag file. In any terminal, manually inspect all published topics and how many messages were published to each topic with this command:
> time rosbag info demo.bag
> OR (if you know part of the topic names of interest before-hand):
time rosbag info mybag.bag | grep -E "(topic1|topic2|topic3)"
- echoing (printing) everything published on required topic, while also teeing it to a file for later review, all in yaml format:
> rostopic echo /obs1/gps/fix | tee topic1.yaml
- Open up another terminal. Subscribe to the other topic
> rostopic echo /diagnostics_agg | tee topic2.yaml
- Repeat this process for as many topics as you like. Each topic must have its own terminal.
- Open up another terminal to play the bag file. We will now play back the bag file as quickly as possible (using the --immediate option), publishing ONLY the topics of interest. The format is:
> time rosbag play --immediate demo.bag --topics /topic1 /topic2 /topic3 /topicN
- *If for some reason one of your rostopic processes missed the messages, just kill its process with Ctrl + C, restart it, and call the rosbag play command again*.
- *On Linux, you can check if roscore is still running or not by something like this (if you see a line like this that includes rosmaster, which starts as part of roscore, roscore is running)*:
> ps -ef | grep -i rosmaster
###### Checking your installation
- **roswtf** examines your system to try and find problems.
> roscd rosmaster
> roswtf
- roswtf uses whatever your current directory is to determine what checks it does. This output is telling us that you started roswtf in the rosmaster package directory.
- ROS Master does not appear to be running.: the roscore isn't running. roswtf didn't do any online checks.
###### Trying it online
- For this step, a Master to be up, so start a roscore in another terminal
> roscd
> roswtf
- roswtf did some online examination of your graph now that your roscore is running. Depending on how many ROS nodes you have running, this can take a long time to complete. roswtf is warning you that the rosout node is subscribed to a topic that no one is publishing to.
- roswtf will warn you about things that look suspicious but may be normal in your system. It can also report errors for problems that it knows are wrong.
> $ roscd
> ROS_PACKAGE_PATH=bad:$ROS_PACKAGE_PATH roswtf
- *There are many other types of problems that --roswtf can find. If you find yourself stumped by a build or communication issue, try running it and seeing if it can point you in the right direction.*
---