|
|
|
# Lab 4: Exploration
|
|
|
|
|
|
|
|
**This is a draft, wait for the lab instructions to be finished before starting**
|
|
|
|
|
|
|
|
The goal of this lab is to fill a knowledge database with information perceived in the environment. You will extend the TST executor of lab3 to listen to a semantic sensor, fill new observation in the database and generate a TST for reaching all the location of interests.
|
|
|
|
|
|
|
|
In this lab you will:
|
|
|
|
* Implement a TST Executor that listen to the semantic sensor topic and fill the database.
|
|
|
|
* Use the `tst_executor` from lab 3 to explore the environment.
|
|
|
|
* Display the results of the exploration in RViz.
|
|
|
|
* Generate a TST to drive to all the locations.
|
|
|
|
|
|
|
|
## Interfacing with the database
|
|
|
|
|
|
|
|
For this lab we will use a Postgresql database, with a wrapper called \emph{kDB} which provides ROS services for executing SQL and SPARQL queries.
|
|
|
|
For this lab, we will only use the SPARQL part.
|
|
|
|
|
|
|
|
The following command will start the database:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
ros2 launch lrs_kdb start_server.launch
|
|
|
|
```
|
|
|
|
|
|
|
|
The database server is very verbose, you can generally ignore what is printed in the terminal.
|
|
|
|
|
|
|
|
You can reset the content of the database with (you need to stop the database first):
|
|
|
|
|
|
|
|
```bash
|
|
|
|
rm -rf $HOME/.lrs_kdb/stores/
|
|
|
|
```
|
|
|
|
|
|
|
|
### Inserting in the database
|
|
|
|
|
|
|
|
The following service call will insert two objects in the graph named **salientpoints**, one human (with identifier 1) at coordinates `(8,10)` and one table (with identifier 2) at coordinates `(10,12)`:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
ros2 service call /husky0/kDBServerNodelet/insert_triples "
|
|
|
|
graphname: 'salientpoints'
|
|
|
|
format: 'ttl'
|
|
|
|
content: '@prefix gis: <http://www.ida.liu.se/~TDDE05/gis>
|
|
|
|
@prefix properties: <http://www.ida.liu.se/~TDDE05/properties>
|
|
|
|
<id1> a <human>;
|
|
|
|
properties:location [ gis:x 8; gis:y 10 ] .
|
|
|
|
<id2> a <table>;
|
|
|
|
properties:location [ gis:x 10; gis:y 12 ] .'"
|
|
|
|
```
|
|
|
|
|
|
|
|
This will insert two objects, the first has uuid `id1`, coordinate `(8,10)` and is a `human`. The second has uuid `id2`, coordinates `(10,12)` and class `table`.
|
|
|
|
|
|
|
|
### Querying the database
|
|
|
|
|
|
|
|
The following query can be used to retrieve all the elements in the database:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
ros2 service call /husky0/kDBServerNodelet/sparql_query "graphnames: ['salientpoints']
|
|
|
|
format: 'json'
|
|
|
|
query: 'SELECT ?x ?y ?z WHERE { ?x ?y ?z }'"
|
|
|
|
```
|
|
|
|
|
|
|
|
The following query can be used to retrieve all the object with their class that are near the point of coordinate `(10, 12)`:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
ros2 service call /husky0/kDBServerNodelet/sparql_query "graphnames: ['salientpoints']
|
|
|
|
format: 'json'
|
|
|
|
query: '
|
|
|
|
PREFIX gis: <http://www.ida.liu.se/~TDDE05/gis>
|
|
|
|
PREFIX properties: <http://www.ida.liu.se/~TDDE05/properties>
|
|
|
|
|
|
|
|
SELECT ?obj_id ?class ?x ?y WHERE { ?obj_id a ?class ;
|
|
|
|
properties:location [ gis:x ?x; gis:y ?y ]
|
|
|
|
FILTER( 9.9 < ?x && ?x < 10.1 && 11.9 < ?y && ?y < 12.1) .
|
|
|
|
}'"
|
|
|
|
```
|
|
|
|
|
|
|
|
You can use `ros2 service info` to get the type of the `sparql_query` service call and `ros2 interface` to access the definition of the service.
|
|
|
|
|
|
|
|
## Semantic sensor
|
|
|
|
|
|
|
|
The sensor output observations on a topic called `/semantic_sensor`. You should use `ros2 topic` and `ros2 interface` to introspect the topic, to find its type, look at the values sent, etc...
|
|
|
|
|
|
|
|
# Exploration
|
|
|
|
|
|
|
|
In [Lab 3](lab3), you have created a TST executor that move the robot to explore the environment. We will extend the functionality of lab3 and add a new type of TST Executor that can be used to record observations from `/semantic_sensor` and save them in the database.
|
|
|
|
|
|
|
|
In `lab3_node`:
|
|
|
|
|
|
|
|
* Create a new TST Executor for `record-semantic`, it takes as parameters
|
|
|
|
** `topic` the name of the topic
|
|
|
|
** `graphname` the name of the graph used to save the data
|
|
|
|
* Listen for new observations on the given topic
|
|
|
|
* Check in the graph specified with `graphname` if the observations are already inserted (using a query). For instance the following query can be used, it should return a single element (you need to replace `someid` and `someclasss` with the correct values from the message):
|
|
|
|
```sparql
|
|
|
|
PREFIX gis: <http://www.ida.liu.se/~TDDE05/gis>
|
|
|
|
PREFIX properties: <http://www.ida.liu.se/~TDDE05/properties>
|
|
|
|
|
|
|
|
SELECT ?x ?y FROM 'salientpoints' WHERE { <someid> a <someklass> ;
|
|
|
|
properties:location [ gis:x ?x; gis:y ?y ] . }
|
|
|
|
```
|
|
|
|
** Make sure to keep `<` and `>` they indicate a URI in the query, without them the query is invalid and will not be executed, so you can replace `<someid>` by `<somethingelse>` but not `somethingelse`.
|
|
|
|
** Replace `salientpoints` with the TST parameter for `graphname`.
|
|
|
|
** This query need to be executed with a service call to `/kDBServerNodelet/sparql_query`. You can check the official tutorial for [Python](https://docs.ros.org/en/galactic/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Py-Service-And-Client.html) or [C++](https://docs.ros.org/en/galactic/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.html) to learn how to make a service call.
|
|
|
|
** In the call to `/kDBServerNodelet/sparql_query`, the fields `bindings` and `service` are unused for this lab and can be set to an empty string.
|
|
|
|
* If the object has not been observed yet in the database. Add new observation using the insert triples service call (replace 'salientpoints' with the TST parameter for `graphname`).
|
|
|
|
* In C++, add `air_simple_sim_msgs` as a dependency in `CMakeLists.txt`, using `find_package` and setting the correct dependencies for your executable.
|
|
|
|
|