-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #633 from osrf/playback_event_recorder
Add playback event recorder
- Loading branch information
Showing
11 changed files
with
2,133 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Playback Event Recorder | ||
|
||
The playback event recorder creates videos for events that are stored in the | ||
events.yml log file in the state log directory. | ||
|
||
Here are the events being recorded and their associated camera mode: | ||
|
||
* robots exiting staging area: static camera above staging area looking down at angle | ||
* rock fall: static camera above dynamic rocks model looking directly downward | ||
* marsupial vehicle detaching child robot: camera follows the child robot | ||
* artifact proximity: camera follows the robot | ||
* region of interest (decision, vertical, elevation): camera follows the robot | ||
|
||
## Running the demo | ||
|
||
To create event videos for a subt log, run: | ||
|
||
``` | ||
bash record_playback_events.bash <path_to_log_dir> | ||
``` | ||
|
||
The script launches ign gazebo in playback mode and creates videos using the | ||
GUI camera video recording feature. For each event, it seeks playback to some | ||
time before the event, moves the camera to the desired location (either in | ||
follow mode or moves to a static pose), and starts recording until some time | ||
after the event. After recording all events, ign-gazebo will exit on its own | ||
and you can find the recorded videos in a timestamped directory inside the | ||
directory where the bash script is run. | ||
|
||
## Video recorder settings | ||
|
||
By default, the video recorder plugin records videos based on real time and | ||
in lower quality than desired. In order to produce smooth high quality videos | ||
with accurate timing, we need to specify a few video recorder | ||
configurations in the `gui.config` file. The config file should be located in | ||
`$HOME/.ignition/gazebo`. Find the 3D Scene plugin and add the following | ||
`<record_video>` settings: | ||
|
||
```xml | ||
<!-- 3D scene --> | ||
<plugin filename="GzScene3D" name="3D View"> | ||
<ignition-gui> | ||
<title>3D View</title> | ||
<property type="bool" key="showTitleBar">false</property> | ||
<property type="string" key="state">docked</property> | ||
</ignition-gui> | ||
|
||
<engine>ogre2</engine> | ||
<scene>scene</scene> | ||
<ambient_light>0.4 0.4 0.4</ambient_light> | ||
<background_color>0.8 0.8 0.8</background_color> | ||
<camera_pose>6 0 6 0 0.5 3.14</camera_pose> | ||
|
||
<record_video> | ||
<use_sim_time>true</use_sim_time> | ||
<lockstep>true</lockstep> | ||
<bitrate>8000000</bitrate> | ||
</record_video> | ||
|
||
</plugin> | ||
``` | ||
|
||
This makes sure the video recording is done in lock step with simulation | ||
state updates so that we do not miss any frames during encoding. Additionally | ||
sim time is used as timestamp so that the generated video length is unaffected | ||
by the speed at which log playback is running in. For example, it may take | ||
up to several hours to playback an event in a subt log due to low RTF but the | ||
resulting video should still have a length that matches the specified duration | ||
of the event. | ||
|
||
## Known issue | ||
|
||
The video recorder configurations are set to produce higher quality videos | ||
but the encoding process is also more expensive. Since the server and the GUI | ||
run asynchronously in two separate processes, we usually see that the GUI start | ||
to lag behind the server after several minutes into recording. Once the ignition | ||
transport msg queue is full, it starts dropping state msgs, and we would | ||
notice missing frames in the generated videos. This is currently mitigated by | ||
using a "catch-up" recording strategy in the playback event recorder, which | ||
basically pauses the simulation when we detect the the video recorder is lagging | ||
behind the server above some threshold, and only resumes playing back simulation | ||
when the lag is within a reasonable amount of time. |
104 changes: 104 additions & 0 deletions
104
subt_ign/scripts/playback_event_recorder/playback_event_recorder.sdf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
<?xml version='1.0'?> | ||
<!-- | ||
Playback event recorder. | ||
This world is used by the record_playback_events.bash script. | ||
Videos will be saved to a timestamped directory inside the directory | ||
where the bash script is run. | ||
To set whether or not the gui camera should follow the entity | ||
during video recording, change the <camera_follow> sdf parameter in the | ||
PlaybackEventRecorder plugin to either true or false. | ||
Usage: bash record_playback_events.bash <path_to_log_dir> | ||
--> | ||
|
||
<sdf version='1.6'> | ||
|
||
<world name='default'> | ||
<!-- | ||
<gui fullscreen="0"> | ||
<plugin filename="GzScene3D" name="3D View"> | ||
<ignition-gui> | ||
<title>3D View</title> | ||
<property type="bool" key="showTitleBar">false</property> | ||
<property type="string" key="state">docked</property> | ||
</ignition-gui> | ||
<engine>ogre2</engine> | ||
<scene>scene</scene> | ||
<ambient_light>0.4 0.4 0.4</ambient_light> | ||
<background_color>0.8 0.8 0.8</background_color> | ||
<camera_pose>6 0 6 0 0.5 3.14</camera_pose> | ||
</plugin> | ||
<plugin filename="WorldControl" name="World control"> | ||
<ignition-gui> | ||
<title>World control</title> | ||
<property type="bool" key="showTitleBar">false</property> | ||
<property type="bool" key="resizable">false</property> | ||
<property type="double" key="height">72</property> | ||
<property type="double" key="width">121</property> | ||
<property type="double" key="z">1</property> | ||
<property type="string" key="state">floating</property> | ||
<anchors target="3D View"> | ||
<line own="left" target="left"/> | ||
<line own="bottom" target="bottom"/> | ||
</anchors> | ||
</ignition-gui> | ||
<play_pause>true</play_pause> | ||
<step>true</step> | ||
<start_paused>true</start_paused> | ||
</plugin> | ||
<plugin filename="WorldStats" name="World stats"> | ||
<ignition-gui> | ||
<title>World stats</title> | ||
<property type="bool" key="showTitleBar">false</property> | ||
<property type="bool" key="resizable">false</property> | ||
<property type="double" key="height">110</property> | ||
<property type="double" key="width">290</property> | ||
<property type="double" key="z">1</property> | ||
<property type="string" key="state">floating</property> | ||
<anchors target="3D View"> | ||
<line own="right" target="right"/> | ||
<line own="bottom" target="bottom"/> | ||
</anchors> | ||
</ignition-gui> | ||
<sim_time>true</sim_time> | ||
<real_time>true</real_time> | ||
<real_time_factor>true</real_time_factor> | ||
<iterations>true</iterations> | ||
</plugin> | ||
</gui> | ||
--> | ||
|
||
<plugin filename='ignition-gazebo-scene-broadcaster-system' | ||
name='ignition::gazebo::systems::SceneBroadcaster'> | ||
<state_hertz>25</state_hertz> | ||
</plugin> | ||
<plugin | ||
filename='ignition-gazebo-log-system' | ||
name='ignition::gazebo::systems::LogPlayback'> | ||
<path>tmp_record</path> | ||
</plugin> | ||
|
||
<plugin | ||
filename="ignition-gazebo-user-commands-system" | ||
name="ignition::gazebo::systems::UserCommands"> | ||
</plugin> | ||
|
||
<plugin | ||
filename="libPlaybackEventRecorder.so" | ||
name="subt::PlaybackEventRecorder"> | ||
<log_path>tmp_record</log_path> | ||
<exit_on_finish>true</exit_on_finish> | ||
<spawn_light>true</spawn_light> | ||
</plugin> | ||
|
||
</world> | ||
</sdf> | ||
|
57 changes: 57 additions & 0 deletions
57
subt_ign/scripts/playback_event_recorder/record_playback_events.bash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/bin/bash | ||
|
||
# The playback event recorder creates videos for events that are stored | ||
# in the events.yml log file in the state log directory. The script launches | ||
# ign gazebo in playback mode and creates videos using the gui camera video | ||
# recording feature. For each event, it seeks playback to some time before the | ||
# event, moves the camera to the desired location, and starts recording until | ||
# some time after the event. | ||
|
||
echo "===================================" | ||
echo "Staring Playback Event Recorder" | ||
echo "===================================" | ||
|
||
if [ -z "$1" ]; then | ||
echo "Usage: bash ./record_playback_events.bash [path_to_log_dir]" | ||
exit 0 | ||
fi | ||
|
||
logDirPath=$1 | ||
|
||
if [ ! -d "$logDirPath" ]; then | ||
echo "Directory does not exist: $logDirPath" | ||
exit 0 | ||
fi | ||
|
||
scriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
tmpDir="tmp_record" | ||
|
||
echo "Creating tmp dir for recording: $tmpDir" | ||
|
||
if [ -d "$tmpDir" ]; then | ||
rm -fr $tmpDir | ||
fi | ||
|
||
ln -s $logDirPath $tmpDir | ||
|
||
echo "Starting log playback and video recording" | ||
|
||
export IGN_GAZEBO_SYSTEM_PLUGIN_PATH=$LD_LIBRARY_PATH | ||
sdfName="playback_event_recorder" | ||
ign gazebo -v 4 "$scriptDir/$sdfName.sdf" | ||
|
||
echo "Video recording ended. Shutting down playback" | ||
|
||
pgrep -f $sdfName | xargs kill -9 &> /dev/null | ||
|
||
videoDir=$(date +%s) | ||
echo "Moving mp4 videos to dir: $videoDir" | ||
mkdir $videoDir | ||
mv *.mp4 $videoDir | ||
|
||
# remove tmp dir | ||
if [ -d "$tmpDir" ]; then | ||
rm -fr $tmpDir | ||
fi | ||
echo "Done" | ||
|
Oops, something went wrong.