Homework 1
Task 0 (Preliminaries)
Task 0.1 (Reading the Guidelines)
- Carefully read the homework submission guidelines.
 - Be sure to follow these guidelines for every assignment.
 
Task 0.2 (Making a Git Repository)
- Create a git repository using the github classroom link (sent separately).
 - All packages made for this class should be a subdirectory in this git repository.
 - You will be expected to maintain this git repository throughout the whole quarter.
 
Task 0.3 (Making a README)
Add a file called
README.mdto the base directory of the repository, based on the following template:# ME495 Sensing, Navigation and Machine Learning For Robotics * <First Name> <Last Name> * Winter 2022 # Package List This repository consists of several ROS packages - <PACKAGE1> - <one sentence description>
- Replace the 
<ITEM>with the appropriate item in the template above. - Add this 
README.mdto your repository and commit. - Whenever you add a new package, list it in this 
README.md - Linux is case-sensitive. 
Readme.mdandREADME.mdare not the same file asREADME.md 
Task 0.4 (Making a Tasks.md)
- Add a file called 
Tasks.mdto the repository - Whenever a task is complete, list it in this file on its own line.
 
Task A (Robot Description)
The goal of this task is to adapt the model in the turtlebot3_description for our needs.
Throughout this project, we may have reason to visualize multiple turtlebots in rviz simultaneously:
for example we may want to see the estimated turtlebot location and the actual turtlebot location.
Upon completion, you will be able to display multiple turtlebot3 models in rviz, each appearing
with a different color. You will also be able to change the physical properties of the robot by
editing a yaml file.
Task A.1 (nuturtle_description package)
- Create an 
ament_cmakeROS package callednuturtle_description.- This should be a directory within your repository (i.e., 
<repo>/nuturtle_description) - The package will contain urdf files and basic debugging, testing, and visualization code for the robots you will be using in this class
 
 - This should be a directory within your repository (i.e., 
 - Update the 
package.xmlas follows:- Give it version number of 
0.1.1 - Provide a descriptive description.
 - Fill in your name and email address as the maintainer and as an author
 - Set the License to APLv2 (the Apache License 2.0). You could use a different one but this is what turtlebot3 code is released under)
 - The package has an 
exec_dependfor the packages used in its launchfiles, so these should be updated appropriately. - It also has an 
exec_dependonros2launch 
 - Give it version number of 
 - If you modify files from the turtlebot3 repository, include a comment at the top of that file stating that it has been modified from the original version (as per APLv2).
 - The package (like all packages you write) must pass 
colcon testwith no warnings or problems. - HINT: It is a good idea to commit after creating the initial package but before it actually does anything.
 
Task A.2 (visualization)
- Write a launchfile called 
load_one.launch.py(in<repo>/nuturtle_description/launch) that loads theturtlebot3_burgerURDF into arobot_state_publisherand optionally allows viewing it in rviz.- The argument 
use_rviz(trueorfalse, defaulttrue) controls whether rviz is launched. - The argument 
use_jsp(trueorfalse, defaulttrue) controls whether thejoint_state_publisheris used to publish default joint states. ros2 launch nuturtle_description load_one.launch --show-argsshould print documentation for the launchfile arguments.- This is the last reminder that all launchfile arguments must be documented: see the guidelines
 
- The appropriate 
rvizconfiguration should be stored innuturtle_description/config/basic_purple.rviz - If 
rvizis launched, the launchfile should terminate whenrvizis closed- Hint: Read required nodes in its entirety.
 
 - See Launch Notes
 
 - The argument 
 - Copy the minimal set of 
mesh(e.g.,.stl) andurdf/xacrofiles from thehumble-develbranch of theturtlebot3_descriptionpackage required to display the turtlebot- Do not include any files that are not necessary.
 - Include all the necessary 
.stlfiles in the basemeshes/subdirectory and do not keep thebases/,sensors, andwheels/sub-directories. - Make sure that when copied to your repository the 
.stlfiles have the proper permissions (e.g. are not executable).- Be careful as they are executable in the 
turtlebot3repository. 
 - Be careful as they are executable in the 
 - If you use 
.urdffiles (as opposed to.urdf.xacrofiles) rename them to.urdf.xacroand set them up to use xacro, as we will be modifying them later and need xacro. 
 - Modify the 
urdf/xacrofiles so that themeshesare able to be loaded from their new location, as installed into the install space of your repository- Remember, all files that you want to use must be installed via the 
CMakeLists.txt 
 - Remember, all files that you want to use must be installed via the 
 - No 
turtlebot3_packagesshould need to be installed forros2 launch nuturtle_description load_one.launchto work.- Be careful here. The 
urdffiles, by default, load assets from theturtlebot3_descriptionpackage, so you need to modify this behavior. - If you temporarily move the 
meshesin your package and everything still works, the assets are likely being loaded from theturtlebot3_descriptionpackage 
 - Be careful here. The 
 - Your launchfile should be written in a declarative style, which means that it
- Should not use any variables
 - The entire launch description should be returned from a single return statement
 - Hint: See this example for how to load a xacro URDF into the 
robot_state_publisher 
 
Task A.3 (yaml File)
- Create 
<repo>/nuturtle_description/config/diff_params.yamlfile to provide a complete parametric description of a differential drive robot.- Not all these parameters will be used in this assignment, but they will be useful later
 
 - You should have the following parameters:
wheel_radius: The radius of the wheels (see: Turtlebot3 Specifications)track_width: The distance between the wheels (see: Turtlebot3 Specifications)motor_cmd_max: 265. The motors are provided commands in the interval[-motor_cmd_max, motor_cmd_max]motor_cmd_per_rad_sec: Each motor command unit (mcu) is0.024 rad/sec(i.e.,1 mcu = 0.024 rad/sec)encoder_ticks_per_rad: The number of encoder ticks per radian. One revolution of the wheel is \(2^{12}\) ticks because it is a 12-bit encoder. (i.e. \(2^{12} \mathrm{ticks} = 2 \pi \mathrm{rad}\))collision_radius: Set this to be0.11. This is some simplified geometry used for collision detection
 - Modify the 
turtlebot3URDF so that it uses the parameters fromdiff_params.yamlsuch that- Changing 
wheel_radiuschanges the collision geometry of the wheels - Changing 
track_widthchanges the distance between the wheels - The 
base_linkof the robot uses thecollision_radiusas follows:- The cylinder should be the same height as the box it is replacing
 - If 
collision-radiusis negative, the original box collision geometry is used 
 - Hint: in XML, '<' and '>' are special characters reserved for tags. Use 
<and>to represent them when they are used as attributes 
 - Changing 
 - See Xacro Notes
 
Task A.4 (prefix)
Throughout this project we will need to track and display multiple robots.
Toward this end, we will add an argument called color to the robot's xacro file, which will change the color of the robot
and launch nodes corresponding to each robot in their own respective namespaces.
- Modify the xacro URDF files to take an argument called 
color: possible values arered,green,blue, andpurple.- The RGB values for Purple are Northwestern Purple: Red: 0.3, Green: 0.16, Blue: 0.52
 
 - Based on the value of 
color, the resulting URDF file should set the color of thebase_linkappropriately - Modify 
load_one.launch.pyto accept an argument calledcolor(defaulting topurple) that- Determines the 
colorthat is passed to thexacrofile as an argument (be sure to document it).- Use the 
choiceskeyword argument toDeclareLaunchArgumentto automatically document and restrict the value to valid colors 
 - Use the 
 - Determines the namespace in which all nodes (including 
rviz) are launched (namespace used is the value ofcolor) - Sets the 
frame_prefixparameter of therobot_state_publishersuch that alltfframes published are prefixed withcolor/ - Set the appropriate Tf-prefix in the Robot View in rviz
- HINT: you may need to create a separate rviz configuration file for each color (
basic_<color>.rviz) - HINT: The 
launch.actionSetLaunchConfigurationlet's you create aLaunchConfigurationfrom substitution rules, which can be concatenated using a list. So you can build the name of the file usingSetLaunchConfigurationand access it later. 
 - HINT: you may need to create a separate rviz configuration file for each color (
 - Sets the appropriate 
fixed_frameinrviz, without changing the.rvizconfiguration file (hint: seerviz2 --help). - Using the 
choicesargument toDeclareLaunchDescription, restrict the value ofcolorto be only the valid values (supported colors and empty ""). 
 - Determines the 
 
Task A.5 (multi robot)
In this task we will test the ability to load multiple independent robots in rviz.
- Create an XML launchfile called 
load_all.launch.xmlthat loads thered,green,blue, andpurplerobots and displays them inrviz- Create and save the configuration in 
config/basic_all.rviz 
 - Create and save the configuration in 
 - This launchfile should include 
load_one.launch.pyseveral times to accomplish its task. - This launchfile should start rviz in the global namespace and terminate the launchfile when rviz closes
- This is accomplished with the "required" attribute to the node tag in ROS 1. It is not implemented yet in ROS2, so just leave it off for now.
 - As of 1/2024 there is a pull request to enable this feature in XML launch files, but it is not released for 
iron. 
 - Each robot should have it's own 
joint_state_publisherandrobot_state_publisherin the appropriate<color>namespace (i.e.,red/,green/,blue/, orpurple/) - The locations of the robots should be as follows:
redis at (0.3,0,0) in thenusim/worldframegreenis at (0,0.6,0) in thenusim/worldframeblueis at (-0.71,0,0) in thenusim/worldframepurpleis at (0,-0.9,0) in thenusim/worldframe
 - A 
tfview should be added torvizand thenusim/worldframe should be the only frame visible. - In the rviz model tree, rename each model to it's appropriate color
- Instead of four items name "RobotModel", have a "BlueRobot" and a "RedRobot" etc.
 
 - Hint: use 
ros2 run tf2_ros static_transform_publisher --helpfor information on a node that the launchfile can run to publish static transforms 
Task A.6 (README)
Write a README.md for your package based on the following template (fill in the
<X Here>with the appropriate command. Remember to remove the<>:# Nuturtle Description URDF files for Nuturtle <Name Your Robot> * `<Command Here>` to see the robot in rviz. * `<Command Here>` to see four copies of the robot in rviz.  * The rqt_graph when all four robots are visualized (Nodes Only, Hide Debug) is:  # Launch File Details * `<Command To Show Arguments of load_one.launch.py>` `<Output of the Above Command>` * `<Command To Show Arguments of load_all.launch.py>` `<Output of the Above Command>`
- The 
rqt_graphshould be saved as an.svgfrom therqt_graphprogram and stored asimages/rqt_graph.svg. - A screenshot from rviz showing the robots should be saved as 
images/rviz.png - The images must display properly when viewing the README on GitHub
 
Task B (C++ and 2D Transforms)
Here you will begin to write a library called turtlelib for performing 2D rigid body transformations and other
functionality.
You are not permitted to use any libraries other than the C++ standard library to complete this task.
The first steps in this assignment take you through the process of building a non-ros C++ project, first from scratch, then with CMake.
The tasks here are grouped according to what needs to be done, but it is likely not a good idea to simply implement the whole library and then test it. Instead you should read through the tasks and work on them concurrently so you can examine and test your implementation as you go along.
Task B.1 (geometry primitives)
- Create a new directory called 
turtlelibin your base repository.- Set this up as a 
CMakeproject. Include the ability to generate documentation withdoxygenand run unit tests. - You may use the example in CMake Basics to get started, but make sure you read through it and do not have any unnecessary code.
 
 - Set this up as a 
 - This directory will hold the 
turtleliblibrary and associated executables and will be a ROS-Independent CMake Project- Follow the directory structure specified in CMake Basics and be sure to put files in the appropriate locations.
 - I will provide file names but not the full path to each file, they should be placed in the correct location based on what they are for.
 
 - Download geometry2d.hpp
- This file will be a header that is part of a library called 
turtlelib - You are responsible for implementing this file in 
geometry2d.cppand filling in any blank implementations (indicated by{}ingeometry2d.hpp). - You may add 
privatemembers to any class but do not add or modify anypublicmembers or any function prototypes or otherwise add to or modify theturtlelibor global namespaces. - The doxygen style comments in the header files should not be repeated in the implementation files
- It is a matter of style whether to put these detailed comments in the 
.cppor.hppfile - Use doxygen style comments throughout your code for the rest of this course.
 
 - It is a matter of style whether to put these detailed comments in the 
 
 - This file will be a header that is part of a library called 
 
Hints
- For more information about the operator overloading going on in this example see (a good Stack Overflow post)
 - For more information about transforms, see Rigid Body Transformations in 2D
 - Implementing the stream extraction operators 
>>can successfully be done in only a few lines of code.- Simplifications can be made by looking at the specification for operator>>
and the hint in 
geometry2d.hpp 
 - Simplifications can be made by looking at the specification for operator>>
and the hint in 
 - A good strategy for implementation is:
- Write minimal stub functionality that does not work but does compile.
 - Move on to task B.2 to write some tests (which initially fail).
 - Iterate between writing tests and implementing the functionality until both B.1 and B.2 are complete.
 
 
Task B.2 (unit testing geometry)
- In 
test_geometry2d.cpp, test all non-constexpr functions ingeometry2d.hpp- See The Catch2 Tutorial
 - Be sure to use approximate comparisons: see Floating Point Comparisons
- Do NOT use your 
almost_equalimplementation for testing purposes. This function is not designed to provide testing diagnostics, it is for use in an actual system that will require approximate comparisons. 
 - Do NOT use your 
 
 - Every function should have at least one test, including 
operator<<andoperator>>. - The 
normalize_anglefunction is crucial and traditionally a major source of bugs.- Including at least the following cases: \(\pi\), \(-\pi\), \(0\), \(-\frac{\pi}{4}\), \(\frac{3\pi}{2}\), \(-\frac{5\pi}{2}\).
 
 - Make sure the tests all pass! You will be using this library in future assignments so you need your implementation to be correct.
 Catch2 v3 is not shipped with Ubuntu 22.04. Here is how to install it from source:
git clone https://github.com/catchorg/Catch2.git cd catch2 cmake -Bbuild . -DBUILD_TESTING=OFF cmake --build build/ sudo cmake --build build/ --target install
Hints
- It makes sense to iterate with B.1 so that you can use the tests to help you implement functionality
 - The 
std::stringstreamclass will be helpful for testingoperator<<andoperator>>. It lets you use anstd::stringas a stream instead of a file. - Catch2 Tutorial
 
Task B.3 (SE(2) geometry)
- Download se2d.hpp, a 
turtlelibheader file that lets you work with SE(2) geometry.- This file will be a header that is part of the 
turtleliblibrary - Implement the specified functionality in a file called  
se2d.cpp - You may add 
private members to any class but do not add or modify any =publicmembers or any function prototypes or otherwise add to or modify theturtlelibor global namespaces. 
 - This file will be a header that is part of the 
 
Hints
- It will be helpful to iterate by working on B.4, B.5, and B.6 as you implement the required functionality so you can test it as you go.
 
Task B.4 (unit testing SE(2))
- In 
test_se2d.cpptest every function and method inse2d.hpp - You may directly combine your tests with the work of your classmates to achieve this coverage, as long as the following conditions are met:
- You personally must develop and write at least six test cases.
 - You may only share or receive test cases directly from the person who wrote them.
 Each test is annotated with the author's name as follows:
TEST_CASE("inverse", "[transform]") // First Name, Last Name- The author name and test name are listed on their own line in 
citations.txt - Each 
TEST_CASEcan have multiple assertions (e.g.CHECK,REQUIRE) but only one author 
 - We will use the Catch2 v3 framework which is not yet released for Ubuntu
 
Task B.5 (visualization)
It can be difficult to know if your geometry-related code is working without being able to visualize it. Unfortunately there is no generally agreed upon good plotting library for C++. Therefore, you will make your own visualizations by outputting the content to an SVG file (a vector-graphics file format). Although the SVG specification is complicated, the subset that we need is small and can be output by a simple C++ program.
Examine this example svg file in a text editor to understand how SVG (for our purposes) works and what content you will need to produce.
I have commented the file with XML comments (<!-- -->): these do not need to be included in your version.
- Create a new header file 
svg.hppand implementation filesvg.cppinturtlelib. - Design and implement a class called 
Svgin theturtlelibnamespace that lets you "Draw" points, vectors, and coordinate frames (as specified in the example) - You will need some provision to write the SVG to a file, or get the file contents as a string.
 - Write at least unit test for the SVG library in a file called 
test_svg.cpp. Here's how:- Get the Svg class working and verify it manually
 - Use the output from your manually verified example in a test case
 - This way, if you ever make a change that breaks the test example the test will fail.
 
 
Hint
- Modify some values of the sample svg by hand and view the image to get a feel for what they do.
 - You may wish to maintain a separate "testing" program to help.
 - You will need a way to convert between 
turtlelibcoordinate frames and the SVG ViewBox coordinate frame - The location of a point can be determined by a 
Transform2Drelative to the midpoint of the page - Drawing a vector depends on not just the vector's length and direction, but also the position of the vector's tail.
 
Task B.6 (executable implementation)
- Create a file called 
frame_main.cpp, which will compile into an executable calledframe_main. Here is what the program should do:- Prompt the user to enter two transforms: \(T_{ab}\) and \(T_{bc}\).
 - Compute and output \(T_{ab}\), \(T_{ba}\), \(T_{bc}\), \(T_{cb}\), \(T_{ac}\), and \(T_{ca}\) and draw each frame in the 
svgfile (with frame A located at (0, 0)). - Prompt the user to enter a point \(p_a\) in Frame 
{a} - Compute \(p_a\)'s location in frames \({b}\) and \({c}\) and output the locations of all 3 points
- Use purple to draw \(p_a\), brown to draw \(p_b\), and orange to draw \(p_c\).
 
 - Prompt the user to enter a vector \(v_b\) in frame \({b}\)
- Normalize the vector to form \(\hat{v}_b\).
 - Draw \(\hat{v}_b\) with the tail located at \((0, 0)\) in frame \({b}\), in brown.
 - Draw \(v_b\) with tail located at \((0,0)\) in frame \({b}\), in brown.
 
 - Output \(v_b\) expressed in frame \({a}\) and frame \({c}\) coordinates
- Draw \(v_a\) with the tail at \((0, 0)\) in frame \({a}\), in purple.
 - Draw \(v_c\) with the tail at \((0, 0)\) in frame$ \({c}\), in orange
 
 - Output the drawing to 
/tmp/frames.svg. 
 
An example transcript from a running program is presented below.
- Lines that start with 
>are entered by the user, but the>symbol is not actually printed to the screen - It is important that your output format matches the format below precisely, as this output will be read by a computer program
 
Enter transform T_{a,b}: >90 0 1 Enter transform T_{b,c}: >90 1 0 T_{a,b}: deg: 90 x: 0 y: 1 T_{b,a}: deg: -90 x: -1 y: -6.12323e-17 T_{b,c}: deg: 90 x: 1 y: 0 T_{c,b}: deg: -90 x: -6.12323e-17 y: 1 T_{a,c}: deg: 180 x: 6.12323e-17 y: 2 T_{c,a}: deg: -180 x: -1.83697e-16 y: 2 Enter point p_a: >1 1 p_a: [1 1] p_b: [0 -1] p_c: [-1 1] Enter vector v_b: >1 1 v_bhat: [0.707107 0.707107] v_a: [-1 1] v_b: [1 1] v_c: [1 -1] Enter twist V_b: >1 1 1 V_a: [1 0 1] V_b: [1 1 1] V_c: [1 2 -1]- Lines that start with 
 - Run your program using numbers that differ from the ones in my example.
- Create a transcript of the input and save it as 
turtlelib/exercises/B6_frame_input.txt- Running 
frame_main < frame_input.txtshould result in your program running as if you entered each line inframe_input.txtvia the keyboard 
 - Running 
 - Save and commit the output to 
turtlelib/exercises/B6_frame_output.txt- After creating 
B6_frame_input.txtyou can create this file withframe_main < B6_frame_input.txt > B6_frame_output.txt 
 - After creating 
 - Save and commit 
/tmp/frames.svgtoturtlelib/exercises/B6_frames.svg 
 - Create a transcript of the input and save it as 
 
Hint
- Think about how the transforms should work and what should be displayed, then open the image in inkscape.
 - Sometimes, objects will be drawn on top of each other (e.g., points show up in the same location regardless of what frame they are expressed in)
- In inkscape you can select objects and move them around to see what is stacked.
 
 
Task B.7 (conceptual questions)
README.md Template
Answer the questions below in the template for turtlelib/README.md. Copy and paste into your own README.md and then answer the questions inline.
There are also other sections of the README.md that you should fill in as you complete the assignment
# Turtlelib Library A library for handling transformations in SE(2) and other turtlebot-related math. # Components - geometry2d - Handles 2D geometry primitives - se2d - Handles 2D rigid body transformations - frame_main - Perform some rigid body computations based on user input # Conceptual Questions 1. If you needed to be able to ~normalize~ Vector2D objects (i.e., find the unit vector in the direction of a given Vector2D): - Propose three different designs for implementing the ~normalize~ functionality - Discuss the pros and cons of each proposed method, in light of the C++ Core Guidelines. - Which of the methods would you implement and why? 2. What is the difference between a class and a struct in C++? 3. Why is Vector2D a struct and Transform2D a Class (refer to at least 2 specific C++ core guidelines in your answer)? 4. Why are some of the constructors in Transform2D explicit (refer to a specific C++ core guideline in your answer)? 5. Why is Transform2D::inv() declared const while Transform2D::operator*=() is not? - Refer to [[https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#con-constants-and-immutability][C++ Core Guidelines (Constants and Immutability)]] in your answer
Normalize Vector
- Implement the normalize vector functionality (in the 
geometry2dmodule) using the method you decided upon in the conceptual questions. - Include at least one unit test for the normalize functionality.
 
Hints
- Information About Classes
 - The C++ Core guidelines (Classes and Class Hierarchies) section has the answers.
 - The C++ Core guidelines (Constructors, Assignments, and Destructors) section has the answers.
 - You may find guidelines in The C++ Core guidelines (Classes and Class Hierarchies) section helpful.
 - The C++ Core Guidelines (Constants and Immutability) will be helpful.
 
Task C (The Simulator)
We will now create a package that can be used as a simulator and visualizer.
This node, called nusim will  provide a simulated robot environment that we will build upon throughout the course.
The simulator node uses rviz2 for visualization. To start, it will be capable of creating some stationary walls and tracking the position
of a robot.
The basic overall structure of the simulation is as follows:
- Initialization
 - Loop at a fixed frequency until terminated.
 - On each loop iteration:
- Update the state of the world (integrate time forward by some timestep)
 - Publish messages that provide state information as if it were coming from a real robot, and updates the 
rvizvisualization - Process service/subscriber callbacks to get commands for the next time step
 
 
We will separate information that can be only be known/done by the simulation (such as teleporting the robot or exact distance measurements) and information that can be known/done by the robot (such as driving forward or noisy distance measurements) using ROS namespaces.
Anything topics/services/parameters relating directly to the domain of the simulation will be done in the nusim namespace and
should not be accessed by nodes not in that namespace.
It may be useful to start writing the launchfile C.5 prior to finishing some of the other tasks so that you may easily run your code as you work on it.
Task C.1 (nusim package)
- Create an 
ament_cmakeros package callednusim.- This should be a directory within your repository (i.e., 
<reponame>/nusim) - Update the 
package.xmlas follows- Give it a version number of 0.1.2
 - Provide a description other than the default.
 - Fill in your name and email address as the maintainer and as an author
 - Choose a license other than TODO
 - The package has a 
dependonrclcpp - Fill out the other dependencies properly.
 
 
 - This should be a directory within your repository (i.e., 
 - The package must pass 
colcon testwith no warnings or problems, including the default tests that are created when runningros2 pkg create 
Task C.2 (simulation node)
- Create the node 
nusim, the main simulation node, and implement it insrc/nusim.cpp - It should run a main loop at a frequency of 
rate(rateis a parameter to the node)- If 
rateis not specified, default to 200 Hz 
 - If 
 - In the main timer publish an 
std_msgs/msg/UInt64~/timestepvalue, which tracks the current timestep of the simulation- Each time the main timer executes, another timestep of the simulation occurs.
 
 - Implement a 
~/resetservice that restores the initial state of the simulation.- For now, the only state is the 
~/timestepvalue, which should be reset to zero. - As more functionality is added to the simulation, the 
~resetservice will need to do more. 
 - For now, the only state is the 
 - Note the 
~before the topic names. This symbol makes the topic "private" to the node, meaning that if the node is called, for example,nusimthan~/timestepwill resolve tonusim/timestep 
Task C.3 (simulated turtle)
We will next add the turtlebot3 robot to the simulation. The simulation must track, control, and publish information about this robot.
- The actual (ground truth) state of the simulated turtlebot will be represented by the 
redturtlebot from Task A.- The ground truth is known only by the simulator
 
 - The 
nusimshould broadcast a transform between thenusim/worldframe andred/base_footprintframe.- This transform represents the actual pose of the robot.
 - Your control algorithms are never allowed to lookup frames starting with 
nusimas that is ground-truth data known only to the simulator. 
 - The 
nusimshould offer a~/teleportservice that enables moving the robot to a desired \((x, y, \theta)\) pose.- Create a custom service type called 
Teleport.srvand give it 3 double-precision floating point values:x,y,theta - Calling this service is the simulated equivalent of picking the robot up and moving it somewhere.
 
 - Create a custom service type called 
 - The initial pose of the robot should be specified by the parameters 
x0,y0, andtheta0provided to thenusimnode- When the 
nusimstarts, the robot should be at the position specified by these parameters relative to thenusim/worldframe - These values default to 0 if not specified
 
 - When the 
 - When the 
~/resetservice is called, the robot should be restored to its initial location. 
Task C.4 (walls)
- The arena where the robot drives will be rectangular, with walls on the boundary.
 - Allow the user to specify the size of the arena using parameters:
arena_x_lengthis the length of the arena in the world \(x\) directionarena_y_lengthis the length of the arena in the world \(y\) direction- The arena is centered at \((0,0)\),
 - The walls are 
0.25mtall - You can use whatever thickness you would like, but remember that the arena is sized in terms of the free space inside.
 
 - The walls should be red to signify that their location is known only to the simulator.
 - Publish the walls as a 
visualization_msgs/MarkerArraymessage on the~/wallstopic once when the simulator starts.- Use the appropriate QoS settings so that the walls will show up even if rviz subscribes after they are published.
 
 
Task C.5 (cylindrical obstacles)
- Add the ability to add cylindrical obstacles to the environment
 - The cylinders should be 0.25m tall, but can have a variable radius (as specified by the user)
 - The cylinders should be red (locations of the cylinders are ground-truth).
 - All obstacles will be specified as parameters to the 
nusimnode:obstacles/xis a list of the obstacles' x coordinates (float64)obstacles/yis a list of the obstacles' y coordinates (float64)obstacles/xandobstacles/yshould always be the same length or the node should log an error message and exit.obstacles/ris the radius of the obstacles ( float65). We will assume that all obstacles are the same radius.
 - You should be able to specify an arbitrary number of obstacles.
 - The 
nusimshould publish avisualization_msgs/MarkerArraymessage on the~/obstaclestopic once on startup- Use the appropriate QoS settings so that the walls will show up even if rviz subscribes after they are published.
 
 
Task C.6 (nusim launch)
- Write an xml launchfile called 
nusim.launch.xmlthat starts the simulator- The launchfile should start 
rviz,nusim, and load all parameters required to run the simulation - The configuration file for 
rvizshould be stored inconfig/nusim.rviz - When launched, the robot, obstacles, and 
nusim/worldtf frame should be visible - The launchfile should include other launchfiles you've written as needed
 
 - The launchfile should start 
 - The default parameters to run the simulation should be stored in 
config/basic_world.yaml- The basic_world should have three cylindrical obstacles of radius 
0.038m, placed at(-0.5, -0.7),(0.8, -0.8), and(0.4, 0.8). - Start the robot at 
(-0.5, 0.7, 1.28) - We will add to this file as more parameters are required
 
 - The basic_world should have three cylindrical obstacles of radius 
 - The launchfile takes an argument called 
config_fileto thenusim.launchlaunchfile.- This argument should let a user specify a 
.yamlfile to configure the simulator. If blank, use the defaultconfig/basic_world.yamlconfiguration file. 
 - This argument should let a user specify a 
 
Task C.7 (README.md)
Create a README.md for this package. It should provide
- A brief description of the package.
 - Descriptions of the provided 
launchfiles - A description of the parameters that can be used to change simulator settings.
 - Include a screenshot from 
rvizas launched fromnusim.launch- Store the image in 
nusim/images/nusim1.png 
 - Store the image in