---
# System prepended metadata

title: Introduction to ROS2
tags: [NTURT, electrical_system, software, tutorial]

---

# Introduction to ROS2
###### tags: `tutorial` `electrical_system` `NTURT` `software`
##### Author: @QuantumSpawner 

## Introduction

ROS (**R**obotic **O**perating **S**ystem) is one of the most renowned open-sourced software platform for robotics control. With the last version of ROS been released on 2020, ROS2 is the sucessor of ROS that adopts modern technologies and added support for real-time code.

We strongly suggest you to read through this wiki page to better unstand ROS and ROS2, **or you might hardly understand what you're doing in the tutorial**: [Wikipedia: Robot Operating System](https://en.wikipedia.org/wiki/Robot_Operating_System).

## Uses on the race car

ROS on Raspberry Pi was the primarily control system of the race car before we migrated to a lower latency microcontroller system. Though it's currently only used to record, display and upload vehicle data but not controlling the car, we plan to use it as the control system for our driveless vehicle in the future. Hence it's vital for you to understand and be capable to use ROS2.

## Using ROS2

The official website of ROS2 as well as other third party websites already provide excellent tutorials for using ROS2, hence we would not reinvent the wheels and make our version of tutorial for ROS2 here.

### Installation

You do not need to install ROS2 onto your computer as we already provide you with docker container that already has ROS2 installed. Please checkout [Introduction to Docker](/i1FmsWq1Sc6XUv3nDg-8xw) and [NTURacingTeam/docker](https://github.com/NTURacingTeam/docker) about how to utilize it.

### Tutorial

Please follow the instruction on the [official ROS2 tutorial](https://docs.ros.org/en/humble/Tutorials.html) about how to use ROS2.
Additionally, if you want to know the design philosophy and concept of ROS2, please checkout: [ROS2 Concepts](https://docs.ros.org/en/humble/Concepts.html) to better understand how it works.

:::warning
Please go through the **C++** part of the tutorial such as [Writing a simple publisher and subscriber (C++)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html). Because most of our control system is C/C++ based for best performance.
:::

:::warning
Please go through the **python** part of the tutorial in [Intermediate/Launch](https://docs.ros.org/en/humble/Tutorials/Intermediate/Launch/Launch-Main.html) section as python is the recommanded language for a launch file in ROS2.
:::

:::info
Here you only need to complete parts from [Beginner: CLI Tools](https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools.html) to [Intermediate/Launch](https://docs.ros.org/en/humble/Tutorials/Intermediate/Launch/Launch-Main.html) in order to finish the homework and topic.
:::

## ROS2 Homework 1
:::success
Please utilize the provided docker environment.

> Checkout [Introduction to Docker](/i1FmsWq1Sc6XUv3nDg-8xw) for details.
:::

:::success
Please push your homework onto your github repository in the `ros2_homework1` directory.

> Checkout [Introduction to Git](/Fy5NKTYBTze8_DHvFY5LhA) for details.
:::

As you go through the tutorials of ROS2, you will also end up with various code examples form the tutorial. Please collect and hand in those to us.

## ROS2 Homework 2
This is a more challenging homework for whom wants to get more familiar about how to write and operate ROS2 topics.

:::success
Please push your homework onto your github repository in the `ros2_homework2` directory.
:::
### Part 1
:::success
Write your answer in the README file in the `ros2_homework2` directory and number them properly.
:::
#### Question 1-1
What is the ROS2 topic communication used for?
Please breifly give a explaination around 50 words
#### Question 1-2
The code below is a ROS2 node printing the number from 1~5 to a topic called "countValues" with a rate of 1 Hz.
- Please fill the missing part of code when you see the comment: "// Fill the missing line of code"
    Some clues will be provided in the comment section.
- Please write a proper comment for the any line of code with "// Explain this line" comment following.

```cpp=
#include "rclcpp/rclcpp.hpp"
// Fill the missing line of code
// Hint: include the ROS2 integer 32 bit library for messaging

int main(int argc, char** argv)
{
    rclcpp::init(argc, argv); // Explain this line
    auto node = rclcpp::Node::make_shared("publisher_node"); // Explain this line
    auto publisher = node->create_publisher<std_msgs::msg::Int32>("count_values", 10); // Explalin this line
    
    // 
    rclcpp::Rate loop_rate(1);
        
    int count = 1;
    while (rclcpp::ok() && count <= 5)
    {
        auto msg = std_msgs::msg::Int32();
        // Fill the missing line of code
        // Hint: makes the content of "msg" to be the value of "count" variable

        publisher->publish(msg);
        RCLCPP_INFO(node->get_logger(), "Publishing: %d", msg.data); // Explain this line
        // Fill the missing line of code
        // Hint: execute the callback function under the "node" node

        loop_rate.sleep();
        count++;
    }
    
    rclcpp::shutdown();
    return 0;    
}
```

For example:
```cpp=
#include <iostream>
using namespace std;
void speakSomething()
{
    // Fill the missing line of code
    // Hint: print out the message "Hellow world!" including a new line
    
    return 0;
}
int main()
{
    speakSomething(); // Explain this line
    return 0;
}
```
The answer for reference:
```cpp=
#include <iostream>
using namespace std;
void speakSomething()
{
    // Fill the missing line of code
    // Hint: print out the message "Hellow world!" including a new line
    cout << "Hellow world" << endl;
    return 0;
}
int main()
{
    // Call and execute the "speakSomething" function
    speakSomething(); // Explain this line
    return 0;
}
```

### Part 2
:::success
Please utilize the provided docker environment.

> Checkout [Introduction to Docker](/i1FmsWq1Sc6XUv3nDg-8xw) for details.
:::

:::success
Please document your code using doxygen.

> Checkout [Introduction to Doxygen](/22VEFY9LR5WINtGCGCi6QA) for details.
:::
In the race team, many scenarios require the communication of different system parts, that is when the ROS2 nodes come into play. For instance, our system needs to detect how much the accelerator pedal is pressed and convert it into a signal which will determine the motor output power.

All the files and ROS2 nodes required in this part is provided in the GitHub repository below:
[Race Team HW Part 2 Repository](https://github.com/heymosbrother/raceteam_softwareHW_2023.git)
Feel free to utilize the files and remember to clone the required files to your own GitHub repository and push your answer before the due date.

#### Scenario Description
- A stroke sensor installed on the accelerator will detect how much the pedal is pressed and return a data within 0~4095 according to the pressed depth (larger is deeper).
    A ROS2 bag file containing pedal stroke data within a period of time is provided in ***/rosbag2_2023_08_22-09_00_33_0*** inside the given GitHub repository.
- A Node called **motor_node** which represents the motor will:
    - Read the PWM signal within 0~255 published under the **pwm_signal** topic.
        > - When the sent signal is 0, there will be 0 volts going through the motor.
        > - When the sent signal is 255, the motor will run under its maximum voltage (500V for example). 
    - Spit out the rotational speed with the unit of revolution per second (revs/s) by publishing it under the ***motor_revs*** topic.

    The ***motor_node*** is provided at ***/src/motor_node.cpp*** in the GitHub repository.
    Note that there are *no direct relations* between the given voltage and motor rotational speed.

- The principle of feeding PWM signal to the motor according to the pedal stroke value is linear. For example, if the pedal stroke is 2047, you should send a PWM signal with the value of 127 to the motor.

#### Your mission
- Write a ROS2 Cpp node called ***stroke_to_pwm_node*** listening to the ***pedal_stroke*** topic and send the corresponding PWM signal to the motor by publishing it under the ***pwm_signal*** topic.

- Use ROS2 bag to record the motor rotational speed published under the ***motor_revs*** topic. And place the file under **/bag_files** directory in your GitHub repository.
    
- (Bonus) Make a screenshot of the ***rqt graph*** while running this project, which will help you understand the node structure better. And append the **.png** image file in your GitHub repository.

Your GitHub repository should look like this:
```bash
some_directory_in_your_raceteam_HW_repository
├── README (your answer to Part 1)
├── CMakeLists.txt
├── package.xml
├── bag_files
│   └── rosbag2_2023_08_22-09_00_33 (the provieded one containing pedal stroke data)
│   └── rosbag2_******** (the bag file you record)
├── src
│   └── motor_node.cpp (the provided node)
│   └── stroke_to_pwm_node.cpp (the node you need to write)
│   └── doxyconfig (doxygen related things)
└── image.png (the rqt graph bonus image)
```
