Experimental run#

#include "navground/sim/experimental_run.h"
struct RunConfig#

Group together parameters to run an experimental run.

Public Members

ng_float_t time_step#

Simulation time step

unsigned steps#

Maximal number of steps to perform

bool terminate_when_all_idle_or_stuck#

Whether to terminate when no progress is possible

struct RecordSensingConfig#

Holds the configuration to record sensing during an experimental run.

Public Members

std::string name#

The name of the dataset group

std::shared_ptr<Sensor> sensor#

The sensor to record, if none, it will the record the behavior sensing state

std::vector<unsigned> agent_indices#

The indices of the agents to record

struct RecordNeighborsConfig#

Holds the configuration to record neighbors during an experimental run.

Public Members

bool enabled#

Whether to record neighbors or not

int number#

The number of neighbors to record. If more, it will record the nearest number record. If fewer, it will pads with zeros.

bool relative#

Whether to use a frame relative to the agent or the absolute frame.

struct RecordConfig#

Holds which data to record during an experimental run.

Public Functions

inline void set_all(bool value)#

Sets all to record or not record.

Parameters:

value[in] The desired value

inline void record_sensor(const std::string &name, const std::shared_ptr<Sensor> &sensor, const std::vector<unsigned> &agent_indices)#

Add a sensor to be recorded.

Parameters:
  • name[in] The name of the group

  • sensor[in] The sensor to record

  • agent_indices[in] The agent indices whose sensing to record

Public Members

bool time = false#

Whether to record the simulation time

bool pose = false#

Whether to record the agents poses

bool twist = false#

Whether to record the agents twists

bool cmd#

Whether to record the agents control commands

bool actuated_cmd#

Whether to record the agents actuated control commands

bool target#

Whether to record the agents targets

bool collisions#

Whether to record collisions

bool safety_violation#

Whether to record safety violations

bool task_events#

Whether to record data from task events

bool deadlocks#

Whether to record the time since when agents are stuck

bool efficacy#

Whether to record efficacy (i.e., fraction of actual velocity vs optimal velocity)

bool world#

Whether to record the initial world state (as YAML)

RecordNeighborsConfig neighbors#

Whether and how to record neighbors

bool use_agent_uid_as_key#

Whether to use uid as keys for sensing and task events. Else it will use the agent index.

std::vector<RecordSensingConfig> sensing#

The sensors to record

Public Static Functions

static inline RecordConfig all(bool value)#

Sets all to record or not record.

Returns:

The configuration.

class ExperimentalRun#

Simulates a world and collects data.

Public Types

enum class State#

The state of the run.

Values:

enumerator init#

The run is ready to be executed

enumerator running#

The run is being executed

enumerator finished#

The run has finished executing

using tp = std::chrono::time_point<std::chrono::steady_clock>#

Time point

Public Functions

inline ExperimentalRun(std::shared_ptr<World> world, const RunConfig &run_config, const RecordConfig &record_config, unsigned seed = 0)#

Construct an ExperimentalRun.

Parameters:
  • world[in] The world to simulate

  • run_config[in] The run configuration

  • record_config[in] The record configuration

  • seed[in] The seed used to initialize the world

inline ExperimentalRun(std::shared_ptr<World> world, ng_float_t time_step, unsigned max_steps, bool terminate_when_all_idle_or_stuck, const RecordConfig &record_config, unsigned seed = 0)#

Construct an ExperimentalRun.

Parameters:
  • world[in] The world to simulate

  • time_step[in] The duration of a simulation step

  • max_steps[in] The maximum number of steps to perform

  • terminate_when_all_idle_or_stuck[in] Whether to terminate when all agents idle or stuck

  • record_config[in] The record configuration

  • seed[in] The seed used to initialize the world

inline std::chrono::nanoseconds get_duration() const#

Gets the real-time duration of the run.

Returns:

The duration in ns or 0 if the run is not yet finished.

inline tp get_begin() const#

Gets when the simulation started.

Returns:

The begin stamp

inline tp get_end() const#

Gets when the simulation finished.

Returns:

The end stamp

inline std::shared_ptr<World> get_world() const#

Returns the simulated world.

Returns:

The simulated world.

inline bool has_finished() const#

Whether the run is finished.

Returns:

True if finished, False otherwise.

inline bool is_running() const#

Whether the run is running.

Returns:

True if running, False otherwise.

inline bool has_started() const#

Whether the run is running or has already finished.

Returns:

True if started, False otherwise.

inline State get_state() const#

Gets the simulation state.

Returns:

The state.

inline ng_float_t get_time_step() const#

Gets the time step used for simulation.

Returns:

The time step.

inline unsigned get_maximal_steps() const#

Gets the maximal number of steps to simulate.

Returns:

The maximal number of steps.

inline bool get_terminate_when_all_idle_or_stuck() const#

Gets whether to terminate when all agents are idle or stuck.

Returns:

Whether to terminate when all agents are idle or stuck.

inline const std::shared_ptr<Dataset> get_record(const std::string &key) const#

Gets the record associated to a given key.

Parameters:

key[in] The key

Returns:

The record or null if none is found.

inline const std::map<std::string, std::shared_ptr<Dataset>> get_records(const std::string &group = "") const#

Gets the records.

Parameters:

group[in] If specified, limits to records in a given group.

Returns:

The records

inline const std::shared_ptr<Dataset> get_times() const#

Gets the recorded times.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_poses() const#

Gets the recorded poses.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_twists() const#

Gets the recorded twists.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_cmds() const#

Gets the recorded commands.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_actuated_cmds() const#

Gets the recorded actuated commands.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_targets() const#

Gets the recorded targets.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_safety_violations() const#

Gets the recorded safety margin violations.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_collisions() const#

Gets the recorded collisions.

Returns:

The record or none if not recorded.

inline std::shared_ptr<Dataset> get_collision_events(unsigned min_interval = 1) const#

Gets the recorded collisions events, i.e. collisions separated by more than min_interval steps.

Parameters:

min_interval[in] The minimal interval between collision among the same pair to be considered a new event

Returns:

The record or none if not recorded.

inline std::shared_ptr<Dataset> get_steps_to_collision(unsigned min_interval = 1) const#

Gets the steps to the next recorded collision for each agent at each simulation step.

Parameters:

min_interval[in] The minimal interval between collision among the same pair to be considered a new event

Returns:

A dataset of shape {#steps, #agents}.

inline const std::map<unsigned, std::shared_ptr<Dataset>> get_task_events() const#

Gets the recorded task logs.

Returns:

The records (empty if not recorded).

inline const std::shared_ptr<Dataset> get_task_events_for(unsigned uid) const#

Gets the recorded task logs.

Parameters:

uid[in] The agent uid or index (if RecordConfig::use_agent_uid_as_key is not set)

Returns:

The record or none if not recorded.

inline const std::map<unsigned, std::map<std::string, std::shared_ptr<Dataset>>> get_sensing() const#

Gets the recorded sensing.

Returns:

The dictionary {id -> {key: sensing data}.

inline const std::map<std::string, std::shared_ptr<Dataset>> get_sensing_for(unsigned id) const#

Gets the recorded sensing.

Parameters:

id[in] The agent uid or index (if RecordConfig::use_agent_uid_as_key is not set)

Returns:

The dictionary {key: sensing data}

inline const std::shared_ptr<Dataset> get_deadlocks() const#

Gets the recorded deadlocks.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_efficacy() const#

Gets the recorded efficacy.

Returns:

The record or none if not recorded.

inline const std::shared_ptr<Dataset> get_neighbors() const#

Gets the recorded neighbors.

Returns:

The record or none if not recorded.

inline unsigned get_recorded_steps() const#

Gets the number of recorded steps.

Returns:

The recorded steps.

inline unsigned get_seed() const#

Gets the recorded number of agents.

Gets the seed used to initialize the simulation.

Returns:

The number of agents.

Returns:

The seed.

inline RecordConfig get_record_config() const#

Gets a copy of the record configuration.

Returns:

The record configuration.

inline std::optional<unsigned> index_of_agent(const Agent *agent) const#

Associate an index to a given agent.

Data related to agents is stored in this order. For example, poses at a given time step are stored as [[x_0, y_0, z_0], [x_1, y_1, z_1], ...]

where the pose of agent a is at the index returned by this function.

Parameters:

agent[in] The agent

Returns:

The index of data related to this agent.

void start()#

Signals that has simulation has started.

Note that this won’t neither execute the simulation nor record data. It will just record the a time stamp and change the state to running.

You don’t need to call start, update, stop, or run when running an Experiment (see Experiment::run instead) but only if you are want to perform a run outside of an Experiment.

Either call start -> update periodically after manually advancing the simulation -> stop, or run once, which does perform all the steps automatically.

void update()#

Signals that data needs to be updated.

Note that this won’t execute the simulation. Use it only between start and stop calls to collect data about the current world state.

Note that after the maximal number of steps has been recorded, it won’t record any more data.

void stop()#

Signals that has simulation has stopped.

Call this after start to stop the recording of a simulation.

You don’t need to call start, update, stop, or run when running an Experiment (see Experiment::run instead) but only if you are want to perform a run outside of an Experiment.

void run()#

Runs a simulation and automatically record data step by step.

You don’t need to call start, update, stop beside run as run manages all the simulation and recording.

You don’t need to call run when running an Experiment (see Experiment::run instead) but only if you are want to perform a run outside of an Experiment.

inline bool has_record(std::string key, const std::string &group = "") const#

Determines if a record is present.

Parameters:
  • key[in] The key

  • group[in] An optional group. If specified, the record with be associated to the key <group>/<key>.

Returns:

True if a record is associated with the key, False otherwise.

inline std::shared_ptr<Dataset> add_record(std::string key, const std::string &group = "", bool force = false)#

Adds a record.

Parameters:
  • key[in] The key

  • group[in] An optional group. If specified, the record with be associated to the key <group>/<key>.

  • force[in] If specified, it will replace the record associated with the key, if already present.

Returns:

The created record

inline void insert_record(std::shared_ptr<Dataset> ds, std::string key, const std::string &group = "", bool force = false)#

Add a record.

Parameters:
  • ds[in] The dataset

  • key[in] The key associated to the record

  • group[in] The group associated to the record. If provided, the effective key will be <group>/<key>

  • force[in] Whether to replace a record if already existing for this key.

inline void add_probe(const std::shared_ptr<Probe> &probe)#

Adds a probe.

Parameters:

probe[in] The probe

template<typename T>
inline void add_record_probe(const std::string &key, bool force = false)#

Adds a record probe.

Parameters:
  • key[in] The key of the record to be created

  • force[in] If specified, it will replace the record associated with the key, if already present.

Template Parameters:

T – The probe class.

template<typename T>
inline void add_group_record_probe(const std::string &key)#

Adds a group record probe.

Parameters:

key[in] The key of the group to be created

Template Parameters:

T – The probe class.

std::set<std::string> get_record_names(const std::string &group = "") const#

Gets the names of records.

Parameters:

group[in] An optional group. If specified, the looks for record associated to keys <group>/....

Returns:

The record names (relative to the group if specified).

std::map<std::string, std::string> get_group(const std::string &name) const#

Gets the record keys in a group.

Parameters:

name[in] The group name

Returns:

A map of record keys {<key>: name/<key>} indexed by keys relative to a group

inline std::string get_world_yaml() const#

Gets the YAML representation of the world at the begin of the simulation..

Returns:

The YAML string.

bool go_to_step(int step, bool ignore_collisions = false, bool ignore_twists = false, bool ignore_cmds = false, bool ignore_targets = false, bool ignore_sensing = false)#

Try to advance the world to a given recorded step.

Depending if the data has been recorded, it will update:

  • poses

  • twists

  • cmds

  • targets

  • sensing

  • time

  • collisions

Parameters:
  • step[in] The step. Negative steps are interpreted as relative to the last registered step, i.e., -1 is the last step.

  • ignore_collisions[in] Whether to skip setting collisions

  • ignore_twists[in] Whether to skip setting twists

  • ignore_cmds[in] Whether to skip setting [last] commands

  • ignore_targets[in] Whether to skip setting targets

  • ignore_sensing[in] Whether to skip setting sensing

Returns:

True if the operation was possible and false otherwise.

void reset()#

Resets the run.

std::set<std::tuple<Entity*, Entity*>> get_collisions_at_step(int step)#

Gets recorded collisions at a given step.

Parameters:

step[in] The step. Negative steps are interpreted as relative to the last registered step, i.e., -1 is the last step.

Returns:

The set of colliding entity pairs.

ng_float_t get_final_sim_time() const#

Gets the last recorded simulation time.

Returns:

The simulation time

BoundingBox get_bounding_box() const#

Gets the rectangle that contains the world during the whole run.

Returns:

The bounding box.

Public Static Functions

static core::Target target_from_data(const std::vector<ng_float_t> &data)#

Decode a target from data stored by a run.

Parameters:

data[in] The data

Returns:

The target

static std::vector<ng_float_t> data_from_target(const core::Target &target)#

Encode a target to be stored by a run.

Parameters:

target[in] The target

Returns:

The data