======= Homework 01 ======= Your task will be to explore a {{ :courses:aro:tutorials:2019-02-20-11-00-56.zip | bagfile }} containing data from a laser scanner (obtained from a real turtlebot). Once you have familiarized yourself with the contents of the bagfile, you should create a node that will collect and process the laser scanner data. After collecting the specified number of samples, the node will plot the collected data. You can find a more detailed description of the individual sub-tasks below. ===== Reading messages from the bagfile ===== - Download the {{ :courses:aro:tutorials:2019-02-20-11-00-56.zip | bagfile }} from the labs web page. Link should be next to the link to this document or: $ wget https://cw.fel.cvut.cz/b202/_media/courses/aro/tutorials/2019-02-20-11-00-56.zip $ unzip 2019-02-20-11-00-56.zip - Check the contents of the bagfile: rosbag info rqt_bag - Find topic name and message type corresponding to data from a laser scanner. This is a device that takes range measurements using laser ranging technique. The laser is incrementally (but very quickly) rotated and a measurement is taken after each increment. Thus, a single scan contains multiple range measurements taken at different angles.Based on the data (ROS message) type, try to find documentation for the laser scanner data (e.g. {{http://wiki.ros.org/sensor_msgs|http://wiki.ros.org/sensor_msgs}}). - Create a node that will listen for the messages from the laser scanner and process them in the following way: - Filter out possibly erroneous data (i.e. outside of the normal value range – see the message documentation) - Discard measurements taken at an angle greater than 30° or lower than -30° (i.e. abs(angle) < 30°) - Compute the mean of the remaining values and store it into a buffer (you can use __Python list__ or __numpy array__) - Store the message timestamp as well (you can store it as a single float using the __to_sec()__ function) - If the number of stored values had reached the number specified in the __plot_length__ global parameter: - Stop accumulating the data - Plot the data - on the X-axis: the timestamps minus the value in the global parameter __start_time__ – that is, each value should represent the number of seconds from the beginning of the bagfile. - on the Y-axis: the computed means - Run all the nodes and then play the bagfile (rosbag play). ===== Plotting ===== Plot the data using the __plot(x, y)__ function of the [[https://matplotlib.org/api/pyplot_api.html|pyplot module]] from the //matplotlib// package. You might also need to use the __show()__ function to show the plot. ===== Setting up the parameters ===== - Next, you will need to set a couple of parameters. - First, set a global parameter with the name __plot_length__ specifying the number of values that shall be collected and plotted. - Set a second global parameter called __start_time__ that will hold the starting timestamp of the ROS bag recording. ===== Hints ===== * You can find most of the necessary information within the presentations from Lab 01. * The rest could be found using the mentioned commands or by following the provided links. * Check [[http://wiki.ros.org/rospy/Overview/Time|http://wiki.ros.org/rospy/Overview/Time]] if you need help with the timestamps. * If you have problem with plotting, search for //matplotlib// plot examples or documentation * When dealing with more complex nodes and persistent variables, it is useful to create a class that will handle all of the data processing. In the case of the listener node, the structure of your script should look like this: #!/usr/bin/env python2 import rospy import numpy as np # TODO other imports class ScanCollector(): def __init__(self): # Initialize the node here # retrieve the necessary parameters from the parameter server # and store them into variables # create the listener object and assign a class method as the callback # possibly do some additional stuff def scan_callback(self, msg): # process the message # if enough data has been collected, plot the data if __name__ == '__main__': sc = ScanCollector() rospy.spin() ===== Example ===== Here is an example of the resulting plot (extracted from the bag with plot_length set to 500): {{ :courses:aro:tutorials:figure_1_hw.png?nolink&800 |}} Your plot might differ a little, depending on the parameters. You also don't need to tune value ranges of the plot axis and the labels (but the plot will look nicer if you do!) ===== Evaluation ===== Please, submit your solution to the [[https://cw.felk.cvut.cz/upload/|upload system]]. Upload only the folder of your package (e.g., "example_package", that contains a "src" folder, and the config files "CMakeList.txt", "package.xml"). Please, do not upload the entire workspace. * The solution must work as described above. * The submitted package must be "buildable" by catkin build in a ROS Melodic distro