From The Player Project
Player supports logging data from sensors, and playing that data back at a later time. Support for these functions are provided by the writelog and readlog drivers. This page provides a basic overview of how to use these drivers to create and play back log files. More detailed information can be found at the data logging tutorial documentation page.
Player comes with example writelog and readlog drivers, you can find them at "$PREFIX/share/player/config/", where $PREFIX is the path to which Player was installed (usually "/usr/local" or "/usr")
In order to log data, you have to use the writelog driver. Writelog subscribes to the devices you specify, and records all data messages coming from the subscribed interfaces to a file. To accomplish this, you'll have to write a configuration file like one below:
# Create a laser device driver ( name "sicklms200" provides ["laser:0"] ) # Create a position2d device driver ( name "p2os" provides ["position2d:0"] ) # Log data from laser:0 to "/home/user/logs/mydata_YYYY_MM_DD_HH_MM_SS.log" driver ( name "writelog" log_directory "/home/user/logs" basename "mydata" requires ["laser:0" "position2d:0"] provides ["log:0"] alwayson 1 autorecord 1 )
As you can see, writelog subscribes to laser:0 provided by the sicklms200 driver, and position2d:0 provided by the p2os driver. All of the data published by sicklms200 and p2os is then recorded to a log file at "/home/user/logs/mydata_YYYY_MM_DD_HH_MM_SS.log". The writelog driver can read from several devices at a time, add as many devices as you want to the "requires" section. All of the data will be recorded to the same logfile.
The writelog driver also queries certain devices for geometry information when it starts. These values are stored at the beginning of the log file, and can be queried from readlog later.
Playing Back Data
To play data from a log file back, the readlog driver must be used. Readlog will read data from a logfile (created by writelog) and play it back through the appropriate interfaces. For example, say we used the above configuration file to record laser data from the sicklms200 device. Now we want to play the log back and have it act like the laser and position2d devices. To do so, we use a configuration file like the one below:
# Play log data back from "/home/user/logs/mydata_YYYY_MM_DD_HH_MM_SS.log" to laser:0 and position2d:0 driver ( name "readlog" provides ["laser:0" "position2d:0" "log:0"] filename "/home/data/logs/mydata_YYYY_MM_DD_HH_MM_SS.log" speed 1.0 )
This driver will publish the data in the log file as though it were coming from real laser and position2d devices. To verify this, use utilities like playerprint or playerv and subscribe to the provided interfaces. The data should be displayed as though it were coming from the physical device the data was recorded from.
Parsing Logs Manually
Player's log files are stored as plain text files. You can open a log with your favorite text editor and see the data that is stored there. Log files all contain the following header information:
## Player version (version) ## File version (version) ## Format: ## - Messages are newline-separated ## - Common header to each message is: ## time host robot interface index type subtype ## (double) (uint) (uint) (string) (uint) (uint) (uint) ## - Following the common header is the message payload
After this header, data begins. Each line of the log file is a data entry, and corresponds to one published message. A sample data line might look like this:
1253043766.043 16777343 6665 position2d 00 001 001 +01.000 +01.000 +1.000 +01.000 +01.000 +01.000 0
The first 7 fields are specified in the header message, and are as follows:
- time (double): The system time when the data message was published
- host (uint): The computer that the data message originated from
- robot (uint): The port that Player was running on
- interface (string): The interface that the message came from
- index (uint): The index of the interface that the message came from
- type (uint): The type of message (PLAYER_MSGTYPE_DATA, PLAYER_MSGTYPE_REQ, etc.)
- subtype (uint): The sub-type of the message (interface specific)