... | ... | @@ -4,7 +4,7 @@ The goal of this lab is to create an executor for Task-Specification-Trees. The |
|
|
|
|
|
## TST
|
|
|
|
|
|
A Task-Specification-Tree (TST) is a hierachical tree structure which represents a complex mission. For the purpose of this lab, six types of nodes are used:
|
|
|
A Task-Specification-Tree (TST) is a hierachical tree structure which represents a complex mission. For the purpose of this lab, six types of TST nodes are used:
|
|
|
|
|
|
You can find the specification of the TST nodes in `air_tst/configs`, the directory on the lab computers is `/courses/TDDE05/software/ros2_ws/src/air_tst/configs`, you can quickly access the directory with:
|
|
|
|
... | ... | @@ -14,8 +14,8 @@ tdde05-cd air_tst configs |
|
|
|
|
|
Here is some documentation:
|
|
|
|
|
|
* `seq` allows to execute a sequence of nodes
|
|
|
* `conc` allows to execute a set of nodes concurrently, it has a parameter `stop-on-first` which controls whether the node should wait for all the children to finish or stop when the first node is done
|
|
|
* `seq` allows to execute a sequence of TST nodes
|
|
|
* `conc` allows to execute a set of TST nodes concurrently, it has a parameter `stop-on-first` which controls whether the TST node should wait for all the children to finish or stop when the first TST node is done
|
|
|
* `dock` and `undock` to dock or undock the robot
|
|
|
* `drive-to` allows to send a ground robot to a specific position, it has the following parameters:
|
|
|
* `p` the destination
|
... | ... | @@ -86,7 +86,7 @@ Bellow is an example, for an exploration mission, in which the robot first move |
|
|
}
|
|
|
```
|
|
|
|
|
|
The `type` indicates the type of TST node, `children` are used by the container nodes and contains other node definition. `params` contains the parameters of each nodes.
|
|
|
The `type` indicates the type of TST node, `children` are used by the container TST nodes and contains other TST node definition. `params` contains the parameters of each TST nodes.
|
|
|
|
|
|
## TstML Library
|
|
|
|
... | ... | @@ -185,7 +185,7 @@ First we need to load the Tst definitions in a `TSTNodeModelsRegistry`. |
|
|
|
|
|
### Python
|
|
|
|
|
|
You will need to create a `TstML.TSTNodeModelsRegistry` and use `loadDirectory` to load all the configuration file. It is best if this `tst_registry` is kept as a class member of your node.
|
|
|
You will need to create a `TstML.TSTNodeModelsRegistry` and use `loadDirectory` to load all the configuration file. It is best if this `tst_registry` is kept as a class member of your ROS node.
|
|
|
|
|
|
```python
|
|
|
import TstML
|
... | ... | @@ -204,7 +204,7 @@ tst_node = TstML.TSTNode.load(filename, tst_registry) |
|
|
|
|
|
### C++
|
|
|
|
|
|
You will need to create a `TstML::TSTNodeModelsRegistry` and use `loadDirectory` to load all the configuration file. It is best if this `tst_registry` is kept as a class member of your node.
|
|
|
You will need to create a `TstML::TSTNodeModelsRegistry` and use `loadDirectory` to load all the configuration file. It is best if this `tst_registry` is kept as a class member of your ROS node.
|
|
|
|
|
|
```c++
|
|
|
#include <TstML/TSTNodeModelsRegistry.h>
|
... | ... | @@ -288,7 +288,7 @@ First you need to create a `NodeExecutorRegistry`, and use the `registerNodeExec |
|
|
#include <TstML/Executor/DefaultNodeExecutor/Sequence.h>
|
|
|
#include <TstML/Executor/DefaultNodeExecutor/Concurrent.h>
|
|
|
|
|
|
// Create a registry with node executors
|
|
|
// Create a registry with TST node executors
|
|
|
TstML::Executor::NodeExecutorRegistry* tst_executor_registry
|
|
|
= new TstML::Executor::NodeExecutorRegistry();
|
|
|
|
... | ... | @@ -334,11 +334,11 @@ Instead of displaying the results, you should set the result in the response of |
|
|
|
|
|
## Implement a subclass of a TstML::AbstractNodeExecutor
|
|
|
|
|
|
The main goal of the lab is to implements executors that are subclass `AbstractNodeExecutor` for the terminal nodes. In this section, I will give you the implementation of the `undock` executor. **It is not enough to copy the file, you need to understand what every lines do. Once you do, call the lab assistant and explain what you think every line does.**
|
|
|
The main goal of the lab is to implements executors that are subclass `AbstractNodeExecutor` for the terminal TST nodes. In this section, I will give you the implementation of the `undock` executor. **It is not enough to copy the file, you need to understand what every lines do. Once you do, call the lab assistant and explain what you think every line does.**
|
|
|
|
|
|
### Python
|
|
|
|
|
|
Executor should inherit the `TstML::AbstractNodeExecutor` class, they need to implement a `start`, `pause`, `resume`, `stop` and `abort` function. They can access parameters for the node in this way:
|
|
|
Executor should inherit the `TstML::AbstractNodeExecutor` class, they need to implement a `start`, `pause`, `resume`, `stop` and `abort` function. They can access parameters for the TST node in this way:
|
|
|
|
|
|
```python
|
|
|
self.node().getParameter(TstML.TSTNode.ParameterType.Specific, "nameoftheparameter")
|
... | ... | @@ -370,7 +370,7 @@ def display_exceptions(func): |
|
|
print(f"Unhandled exception was caught: '{ex}'")
|
|
|
return wrapper
|
|
|
|
|
|
# Ugly hack to get a new name for each node
|
|
|
# Ugly hack to get a new name for each ROS node
|
|
|
ros_name_counter = 0
|
|
|
def gen_name(name):
|
|
|
global ros_name_counter
|
... | ... | @@ -439,7 +439,7 @@ from .name_of_file import NameOfClass |
|
|
|
|
|
### C++
|
|
|
|
|
|
Executor should inherit the `AbstractNodeExecutor` class, they need to implement a `start`, `pause`, `resume`, `stop` and `abort` function. They can access parameters for the node in this way:
|
|
|
Executor should inherit the `AbstractNodeExecutor` class, they need to implement a `start`, `pause`, `resume`, `stop` and `abort` function. They can access parameters for the TST node in this way:
|
|
|
|
|
|
|
|
|
The following show an example of implementation for `undock`:
|
... | ... | @@ -461,7 +461,7 @@ The following show an example of implementation for `undock`: |
|
|
#include <TstML/Executor/AbstractNodeExecutor.h>
|
|
|
#include <TstML/TSTNode.h>
|
|
|
|
|
|
// Ugly hack to get a new name for each node
|
|
|
// Ugly hack to get a new name for each ROS node
|
|
|
std::string gen_name(const std::string& _name)
|
|
|
{
|
|
|
static int counter = 0;
|
... | ... | @@ -577,7 +577,7 @@ Do not forget to add the `UndockExecutor` to the executor registry, like it was |
|
|
|
|
|
## Test execution
|
|
|
|
|
|
You should now start your `tst_executor` node, and we can use a service call to execute our first TST:
|
|
|
You should now start your `tst_executor` ROS node, and we can use a service call to execute our first TST:
|
|
|
|
|
|
```bash
|
|
|
ros2 service call /execute_tst air_lab_interfaces/srv/ExecuteTst "tst_file: '`ros2 pkg prefix air_tst`/share/air_tst/tsts/undock.json'"
|
... | ... | @@ -696,7 +696,7 @@ You need to implement the `dock`, `drive_to` and `explore`. |
|
|
|
|
|
**Drive to** Drive to a given location and set the maximum velocity. To drive to a given location, you should send a goal to the navigate action server, like you did in *Lab 2*. Also in this lab you will need to se the `maximum_speed` by publishing on the `/speed_limit` topic. You can use `ros2 topic info` to get the information about a topic, including its type. You can use `ros2 interface show` to show the definition of a topic. `drive_to` has three parameters that you need to get: the destination `p`, the `heading` and the `maximum-speed`.
|
|
|
|
|
|
To get parameters for a node, in python:
|
|
|
To get parameters for a TST node, in python:
|
|
|
|
|
|
```python
|
|
|
self.node().getParameter(TstML.TSTNode.ParameterType.Specific, "nameoftheparameter")
|
... | ... | |