diff --git a/devices/YarpRobotLoggerDevice/README.md b/devices/YarpRobotLoggerDevice/README.md
index 22d2380943..e217093336 100644
--- a/devices/YarpRobotLoggerDevice/README.md
+++ b/devices/YarpRobotLoggerDevice/README.md
@@ -1,71 +1,137 @@
# YARPRobotLoggerDevice
-The **YARPRobotLoggerDevice** is a YARP device based on `YarpSensorBridge` and `matioCpp` to record dataset from a YARP-based robot.
-
-
-
-## :running: How to use the device
-
-- Launch `yarprobotinterface` on the robot.
-
- Depending on your logger configuration file and on the data you want to collect you should run the main `yarprobotinterface` with a different option. In order to use the [defaul logger configuration files](./app/robots), use the following commands:
- - **iCubGenova04**
-
- launch the `yarprobotinterface` with the `root_imu` device on the robot head
- ```
- yarprobotinterface --config icub_wbd_inertials.xml
- ```
- - **iCubGazeboV3**
-
- open the robot model in gazebo and launch `whole-body-dynamics`
- ```
- YARP_ROBOT_NAME=iCubGazeboV3 yarprobotinterface --config launch-wholebodydynamics.xml
- ```
- in case you started gazebo with the real-time clock option (`gazebo -slibgazebo_yarp_clock.so`) add `YARP_CLOCK=/clock` to the previous command.
- ```
- YARP_CLOCK=/clock YARP_ROBOT_NAME=iCubGazeboV3 yarprobotinterface --config launch-wholebodydynamics.xml
- ```
-
-- Launch the logger device.
-
- In order to use the [defaul logger configuration files](./app/robots), set the `YARP_ROBOT_NAME` environment variable and launch the `yarprobotinterface` as follow
- ```
- yarprobotinterface --config launch-yarp-robot-logger.xml
- ```
-
-- Press Ctrl+c to close the device, and the dataset is stored as the device is closed.
-
-## 💾 Data
-
- Depending on the configuration file, each dataset can contain:
- - `time` vector with the YARP clock time stamps.
- - `joint_state` that containins
- - `joints`: name of the joints
- - `joint_positions`
- - `joint_velocities`
- - `joint_torques`
-- `Motor_state` that contains
- - `motor_currents`
- - `motor_velocities`
- - `motor_positions`
-- `PID`
-- `Motor_PWM`
-- `Accelerometer` struct containing data for each selected source.
-- `CartesianWrench` struct containing data for each selected source.
-- `FT` struct containing data for each selected source.
-- `Gyros` struct containing data for each selected source.
-- `Orientation` struct containing data for each selected source as roll-pitch-yaw euler angles.
-
-## 🏷️ Migrate mat files
-### v0.6.0 -> v0.7.0
-
-To migrate an existing `mat` file saved with the device version `v0.6.0` to `v0.7.0` you can run the matlab script `scripts/migrate_0_6_0_to_0_7_0.m` as
-```matlab
-% name of the robot
-robot_name = 'iCubGenova09';
-
-% path of the folder containing the mat files that will migrate
-files_path = './dataset';
-migrate_0_6_0_to_0_7_0(files_path, robot_name);
+The **YARPRobotLoggerDevice** is a YARP device based on `YarpSensorBridge` and [`robometry`](https://github.com/robotology/robometry) that allows logging data from robot sensors and actuators in a mat file.
+
+## Configuration Parameters
+The logger is currently supported only for the robots listed in the [application folder](./app/robots). Each robot folder contains:
+
+- `launch-yarp-robot-logger.xml`: Configuration parameters for the `yarprobotinterface` to launch the logger device and associated devices.
+- `yarp-robot-logger.xml`: Configuration parameters for the logger device.
+- `blf-yarp-robot-logger-interfaces`: Folder containing all interfaces used by the logger device to log data.
+
+## How to Use the Logger
+To use the logger, launch the `yarprobotinterface` with the `launch-yarp-robot-logger.xml` configuration file:
+
+```console
+yarprobotinterface --config launch-yarp-robot-logger.xml
+```
+When you close the yarprobotinterface, the logger will save the logged data in a mat file. Additionally, a md file will contain information about the software version in the robot setup. If video recording is enabled, a mp4 file with the video recording will also be generated.
+
+## How to log exogenous data
+The `YarpRobotLoggerDevice` can also log exogenous data, i.e., data not directly provided by the robot sensors and actuators. To do this:
+1. modify the `yarp-robot-logger.xml` file to specify the exogenous data to log
+2. modify the application that streams the exogenous data
+
+### Modification `yarp-robot-logger.xml` configuration file
+Modify the [`ExogenousSignalGroup` in the `yarp-robot-logger.xml` file](https://github.com/ami-iit/bipedal-locomotion-framework/blob/a3a8e9cb8a0c3532db81d814d4851009f8134195/devices/YarpRobotLoggerDevice/app/robots/ergoCubSN000/yarp-robot-logger.xml#L27-L37) to log the data streamed by an application that allows the robot to balance:
+ ```xml
+
+
+ ("balancing")
+ ()
+
+
+
+
+ "/yarp-robot-logger/exogenous_signals/balancing"
+
+
+ "/balancing-controller/logger"
+
+
+ "balancing"
+
+
+ "udp"
+
+
+ ```
+
+### Stream exogenous data
+You need to modify the application that streams the exogenous data to open a port with the name specified in the `remote` parameter of the `balancing` sub-group. For example, if you want to stream the data from the your `balancing` application you need to use `BipedalLocomotion::YarpUtilities::VectorsCollectionServer` class as follows
+#### C++
+If your application is written in C++ you can use the `BipedalLocomotion::YarpUtilities::VectorsCollectionServer` class as follows
+
+```c++
+#include
+
+class Module
+{
+ BipedalLocomotion::YarpUtilities::VectorsCollectionServer m_vectorsCollectionServer; /**< Logger server. */
+public:
+ // all the other functions you need
+}
+```
+The `m_vectorsCollectionServer` helps you to handle the data you want to send and to populate the metadata. To use this functionality, call `BipedalLocomotion::YarpUtilities::VectorsCollectionServer::populateMetadata` during the configuration phase. Once you have finished populating the metadata you should call `BipedalLocomotion::YarpUtilities::VectorsCollectionServer::finalizeMetadata`
+```c++
+//This code should go into the configuration phase
+auto loggerOption = std::make_shared(rf);
+if (!m_vectorsCollectionServer.initialize(loggerOption->getGroup("LOGGER")))
+{
+ log()->error("[BalancingController::configure] Unable to configure the server.");
+ return false;
+}
+
+m_vectorsCollectionServer.populateMetadata("dcm::position::measured", {"x", "y"});
+m_vectorsCollectionServer.populateMetadata("dcm::position::desired", {"x", "y"});
+
+m_vectorsCollectionServer.finalizeMetadata(); // this should be called only once
```
-You will find the new datasets in `/v070`
+In the main loop, add the following code to prepare and populate the data:
+
+```c++
+m_vectorsCollectionServer.clearData(); // optional see the documentation
+
+// DCM
+m_vectorsCollectionServer.populateData("dcm::position::measured", );
+m_vectorsCollectionServer.populateData("dcm::position::desired", );
+
+m_vectorsCollectionServer.sendData();
+```
+
+**Note:** Replace `` with the actual data you want to log.
+
+
+#### Python
+If your application is written in Python you can use the `BipedalLocomotion.yarp_utilities.VectorsCollectionServer` class as follows
+```python
+import bipedal_locomotion_framework as blf
+
+class Module:
+ def __init__(self):
+ self.vectors_collection_server = blf.yarp_utilities.VectorsCollectionServer() # Logger server.
+ # all the other functions you need
+```
+The `vectors_collection_server` helps you to handle the data you want to send and to populate the metadata. To use this functionality, call `BipedalLocomotion.yarp_utilities.VectorsCollectionServer.populate_metadata` during the configuration phase. Once you have finished populating the metadata you should call `BipedalLocomotion.yarp_utilities.VectorsCollectionServer.finalize_metadata`
+```python
+#This code should go into the configuration phase
+logger_option = blf.parameters_handler.YarpImplementation(rf)
+if not self.vectors_collection_server.initialize(logger_option.get_group("LOGGER")):
+ blf.log().error("[BalancingController::configure] Unable to configure the server.")
+ raise RuntimeError("Unable to configure the server.")
+
+# populate the metadata
+self.vectors_collection_server.populate_metadata("dcm::position::measured", ["x", "y"])
+self.vectors_collection_server.populate_metadata("dcm::position::desired", ["x", "y"])
+
+self.vectors_collection_server.finalize_metadata() # this should be called only once when the metadata are ready
+```
+In the main loop, add the following code to prepare and populate the data:
+```python
+self.vectors_collection_server.clear_data() # optional see the documentation
+self.vectors_collection_server.populate_data("dcm::position::measured", )
+self.vectors_collection_server.populate_data("dcm::position::desired", )
+self.vectors_collection_server.send_data()
+```
+**Note:** Replace `` with the actual data you want to log.
+
+## How to visualize the logged data
+To visualize the logged data you can use [robot-log-visualizer](https://github.com/ami-iit/robot-log-visualizer). To use the `robot-log-visualizer` you can follow the instructions in the [README](https://github.com/ami-iit/robot-log-visualizer/blob/main/README.md) file.
+
+Once you have installed the `robot-log-visualizer` you can open it from the command line with the following command:
+```console
+robot-log-visualizer
+```
+Then, you can open the mat file generated by the logger and explore the logged data as in the following video:
+
+[robot-log-visualizer.webm](https://github.com/ami-iit/robot-log-visualizer/assets/16744101/3fd5c516-da17-4efa-b83b-392b5ce1383b)