How-to: Log and retrieve data from the robot#
PAL’s robots already has a ROS package that enables publishing log data that is
then written to an internal CSV file, named node_pal_interaction_logger.
pal_interaction_logger
logs the interactions between the robot and the user.
For example, the package can log the interactions with the touchscreen or the
results of speech recognition.
The logger subscribes to a generic std_msgs/String message that contains information about the interaction. The saved log consists of the description of the interaction and the corresponding timestamp.
Note
Another popular option to log data is to use the ROS bag tool to record (and later, replay) arbitrary ROS topic. This is fully supported on the PAL’s robots platform.
ROS bag is more flexible (it can record any ROS topic), but data analysis is
also often more time consuming (the recorded topics typically needs to be
replayed and converted to CSV or JSON before analysis). As such,
pal_interaction_logger
is a good alternative for simple logging needs.
Read more about ROS bag.
Launch pal_interaction_logger#
pal_interaction_logger
can be launched with the following command:
roslaunch pal_interaction_logger pal_interaction_logger.launch
By default pal_interaction_logger
subscribes to the topic
/interaction_logger. The log is saved in the following folder:
${HOME}/.pal/pal_interaction_logger/
under the name
interaction_logger_YYYY_MM_DD.csv
. The default values for the log location
and topic can be set as arguments when launching the logger.
roslaunch pal_interaction_logger pal_interaction_logger.launch log_folder:=/path/to/desired/folder logger_topic:=/custom_topic_name
Publish log data#
Caution
Be mindful of the privacy implications of data logging. We generally recommend not to log data that could uniquely identify people interacting with the robot.
Please only do so after carefully consideration, and, where applicable, approval by your ethics committee.
Learn more on Data management, security, data privacy.
Publish to the /interaction_logger topic:
rostopic pub /interaction_logger std_msgs/String "data: 'game completed'"
Check that the log has been correctly written to the CSV file:
ssh pal@ari-0c
cd /home/pal/.pal/pal_interaction_logger/
cat interaction_logger_2022_11_15.csv
Each new log will result in a new line.
Time,Log
2022-11-15-12:39,game completed
Add pal_interaction_logger
to the robot’s startup#
By default, this node is not running on the robot. If you wish to add it as a startup, follow the instructions in Configure an application to launch at start-up. Specifically, create the following files:
First create a new app
:
ssh pal@ari-0c
cd /home/pal/.pal/pal_startup/apps/
nano interaction_logger.yaml
Paste the following content so that it launches the corresponding node:
roslaunch: "pal_interaction_logger pal_interaction_logger.launch"
dependencies: []
Create a new control
file, or add it to an existing one, that defines custom
programs the robot will execute on boot:
ssh pal@ari-0c
cd /home/pal/.pal/pal_startup/control/
nano my_demo_startup.yaml
Add the interaction logger startup:
- interaction_logger
Reboot the robot for changes to take effect.
Create a custom data logger#
You can easily create your own ROS data logger, to record custom data to a CSV file or to send it to an external database.
While pal_interaction_logger
specifically subscribes to a std_msgs/String message, you
might want to record other topics and message types. You might as well want
additional fields in your CSV file, or the data received transferred to database
such as
MySQL<https://dev.mysql.com/doc/connector-python/en/connector-python-example-connecting.html>.
Note
As indicated above, you can also use ROS bag tool to record and replay arbitrary ROS topic.
Read more about ROS bag.
The following script implements a simple Python data logger. You can adjust it to your needs. Remember to deploy the code on the robot following instructions of Tutorial: Deploying ROS packages on the robot
import rospy
from std_msgs.msg import String
import os.path
import csv
from datetime import datetime
class InteractionLogger():
_csv_filename = ""
_logger_topic = ""
_log_folder = ""
def __init__(self):
self._log_file = None
self.config()
self._logger_sub = rospy.Subscriber(
self._logger_topic, String, self.interaction_callback
)
def config(self):
# Get params
self._log_folder = rospy.get_param("~log_folder", "log")
self._logger_topic = rospy.get_param("~logger_topic", "logging_topic")
# Create the CSV file
self._csv_filename = (
self._log_folder
+ "/interaction_logger_"
+ datetime.now().strftime("%Y_%m_%d")
+ ".csv"
)
# If folder does not exist, create folder
if not os.path.exists(self._log_folder):
os.makedirs(self._log_folder)
# Create csv file with right headers
if not os.path.exists(self._csv_filename):
self.create_log_file()
def open_log(self):
f = open(self._csv_filename, "w")
self._log_file = csv.writer(f)
def interaction_callback(self, msg):
log_data = msg.data
log_time = datetime.now().strftime("%Y-%m-%d-%H:%M")
self.write_log(log_data, log_time)
def create_log_file(self):
self.open_log()
header = ["time", "message"]
self._log_file.writerow(header)
def write_log(self, log, log_time):
if not os.path.exists(self._csv_filename):
self.create_log_file()
if not self._log_file:
self.open_log()
self._log_file.writerow([log_time, log])
if __name__ == "__main__":
rospy.init_node("my_custom_data_logger")
logger = InteractionLogger()
rospy.spin()
See also#
ROS bag (external link)