> For the complete documentation index, see [llms.txt](https://ceri-num.gitbook.io/uv-larm/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ceri-num.gitbook.io/uv-larm/tuto.-01-kick-off/package.md).

# ROS Package

This tutorial is based on the official documentation: [docs.ros.org](https://docs.ros.org), with some tuning considering our preferences... Typically we prefer cmake method, whatever the targeted language (*C++* or *python*).

## Your first package in ROS2

You can build your first package using the ros tool, with the build-type `ament_cmake`, then compile and install the package. Typically a `tuto_kickoff` package:

```sh
ros2 pkg create --build-type ament_cmake tuto_kickoff
colcon build --packages-select tuto_kickoff
```

Package creation generate files identifying `tuto_kickoff` directory as a ROS package source. The file `package.xml` setup the ROS configuration, the name of the packages and its dependencies in ROS ecosystem. The file `CMakeLists.txt` is required to use [CMake](https://en.wikipedia.org/wiki/CMake) tool, a very famous cross-platform tool for automatizing building processes.

The `colcon build` command produces the `build` and the `install` directories with respectively, temporary files generated by the build process and the resulting built executable and resources (yes, none at this point...). To inform your terminal that some ROS resources are available here, you have to [source](https://linuxcommand.org/lc3_man_pages/sourceh.html) the ROS setup file.

```sh
ls
source ./install/setup.bash
```

## The package.xml file

As we said, `package.xml` is the entrance point of the package for ROS tools. It is a text file in [eXtensible Markup Language](https://fr.wikipedia.org/wiki/Extensible_Markup_Language) format. Typically, it regroups all the dependencies, for instance `rclcpp` and `rclpy` the ROS client libraries for Cpp and Python or `std_msgs`. [std\_msgs](https://index.ros.org/p/std_msgs) and [geometry\_msgs](https://index.ros.org/p/geometry_msgs) are a ROS package defining the format of the simple and common messages allowing the communication between ROS processes (standard and geometry messages for our use).

In the `package.xml` file :

```xml
<package format="3">
  ...
  <depend>rclcpp</depend>
  <depend>rclpy</depend>
  <depend>std_msgs</depend>
  <depend>geometry_msgs</depend>
  ...
</package>
```

Those lines inform ROS to make the targeted resources available at build and execution time. For information about `package.xml` you can refer to the official specifications on [www.ros.org](https://www.ros.org/reps/rep-0149.html).

## The CMakeList.txt

The `CMakeList.txt` provide instructions on how to build libraries and programs. Generally, the file starts with a project name and the importation of dependencies. The dependencies must be installed, reachable on the machine and with the appropriate version number. Then its define how to build new resources (typically, libraries and programs/executable). And finally the element to install and where.

For instance, all launch file included in the `launch`s directory can be installed with the cmake command:

```sh
# Install launch files.
install(DIRECTORY
  launch
  DESTINATION share/${PROJECT_NAME}/
)
```

Most of the primitive (`find_package`, `add_executable`, `install`) and macros (`PROJECT_NAME`, `REQUIRED`, ... ) are CMake primitives and macros. The `ament` tools provides some of primitive dedicated to [ROS build automation](https://docs.ros.org/en/foxy/How-To-Guides/Ament-CMake-Documentation.html).

## Python scripts with Cmake

Scripts are short executable code file, defining a ROS Node (in our context).

The simplest way to include Python-based ROS node depending on a specific [Python Package](https://docs.python.org/3/glossary.html#term-package) is to use `install` instruction in `CMakeLists.txt`. Considering that your work is in a `scripts` directory and knowing that the ROS destination to make the resources available for `ros2 run` is `lib` (...), the install instructions would look-like:

```sh
# Python scripts
install( PROGRAMS scripts/myNode DESTINATION lib/${PROJECT_NAME})
```

Naturally, it supposes that you have `myNode` script file aside. A minimal `myNode` can look-like :

```python
#!/usr/bin/python3
import rclpy                 # core ROS2 client python library
from rclpy.node import Node  # To manipulate ROS Nodes

def main():
    rclpy.init()     # Initialize ROS2 client
    myNode= Node('blanc_node') # Create a Node, with a name         

    # Start the ros infinite loop with myNode.
    rclpy.spin( myNode )

    # At the end, destroy the node explicitly.
    myNode.destroy_node()

    # and shut the light down.
    rclpy.shutdown()

    print("tuto_move :: STOP.")

# If the file is executed as a script (ie. not imported).
if __name__ == '__main__':
    # call main() function
    main()
```

**ATTENTION**, The `#!/usr/bin/python3` in the first line is mandatory. It indicate the interpreter processing the script. In fact, you have a executable program named `python3` in the location `/usr/bin`.

## Run your node:

Build your packages, from your workspace directory, and update your shell environment with `source`.

```sh
colcon build
source install/setup.bash
```

Normally, at this point a new package `tuto_kickoff` with `myNode` is reachable by `ros2`.

```sh
ros2 run tuto_kickoff myNode
```

The executed `myNode` script is the one in `install/tuto_kickoff/lib`. Any modification in your script files would require a new `colcon build` for propagation in ros ecosystem.

## Exercice:

1. Add the node developed into the tutorial "*move the robot*" into your package `tuto_kickoff` as a `move_tbot`s node. At the end, you will be capable of starting it with the command: `ros2 run tuto_kickoff move_tbot`.
2. Add a launch file starting a gazebo simulation with the `move_tbot` node. At the end, you will be capable of launching gazebo, a robot, your control node with the command: `ros2 launch tuto_kickoff sim_move_launch.yaml`.
