Log-based Simulation

You can replay a log into a pipeline to simulate your software stack. This allows you to simulate what “would have happened” if your new software was running on the robot at the time the log was recorded.

There are a few methods you can use to run a log-based simulation.

Through Main

The main::Main() system automatically provides a mechanism to add the necessary stages to your pipeline to execute a log-based simulation.

For example:

#include "ark/main/main.hh"
#include "ark/pipeline/pipeline.hh"

// Construct a pipeline.
ark::pipeline::Pipeline;

// ... Add your stages here ...

// Execute the pipeline.
return main::execute_simclock_pipeline(argc, argv, std::move(pipeline), ark::main::MainConfiguration::LogPlaybackConfiguration());

This will automatically add log access and other command line options to an argument parser, and then add a LogReaderStage with the appropriate configuration to your pipeline. It will execute until the log completes.

Manually Adding a LogReaderStage

If you prefer to do things manually, without the assistance of main::Main(), you can still execute a log-based simulation through a combination of using the LogReaderStage and the SimClockExecutor.

As a trivial example:

// Setup the log reader to load a particular log.
ark::logging::LogReaderStageConfiguration reader_config;

reader_config.log_url = "<path/to/your/log>";

// Setup your config package.
config::ConfigPackage package;
package.register_config_structure("LogReaderStage", reader_config);

// Construct the pipeline and attach your custom `MyStage` to the log reader.
ark::pipeline::Pipeline;

pipeline.set_config_package(package);

pipeline.add_stage<ark::logging::LogReaderStage>();
pipeline.add_stage<MyStage>();

ark::pipeline::SimClockExecutor executor(std::move(pipeline));
executor.execute();

Data will be read from the log and injected into the pipeline at the precise times that it was logged on-vehicle. Because the SimClockExecutor is deterministic, the results of this code will be identical each time you run it.

The main caveat with this approach is that the logged data will not react to changes in your system. For example, if your robot decides to go left instead of right, the logged data will continue to go right.

Writing an Amendment

You can use the LogAmenderStage to write out an amendment containing new algorithm data.

Add this to an existing pipeline with:

#include "ark/logging/stages/log_amender_stage.hh"

// Setup the configuration of the amender.
ark::logging::LogAmenderStageConfiguration amender_config;

amender_config.input_url = reader_config.log_url;
amender_config.output_path = "/tmp/ark_logs";

// Setup your config package.
config::ConfigPackage package;
package.register_config_structure("LogAmenderStage", amender_config);

// Add this stage to your existing pipeline.
pipeline.add_stage<ark::logging::LogAmenderStage>();

Afterwards, you can execute your pipeline as normal. An amendment will be generated in the output path that you specified.