State Estimations#
At the begin of a simulation, prepare
(C++
, Python
) is called: override it to initialize the state estimation.
The base implementation is empty, therefore it is not required to call it.
During the simulation, update
(C++
, Python
) is called before a behavior is executed: override it to update the environment state of the agent’s behavior (C++
, Python
).
As the behavior may have any type of environment state, you should check that is support the interface your state estimation requires.
In case your behavior uses an new type of environment state, you will need to define at least one state estimation supporting it.
Another reason to define a new state estimation may be to implement a specific error model or sensing limitation.
Virtual methods#
Class skelethon#
#include "navground/sim/state_estimation.h"
namespace core = navground::core;
namespace sim = navground::sim;
struct MyStateEstimation : public sim::StateEstimation {
// CAN override
// executed at the start of the simulation
// void prepare(sim::Agent * agent, sim::World * world) override;
// CAN override
// executed during the the simulation
// update the environment state according to the agent and world
void update(sim::Agent *agent, sim::World *world,
core::EnvironmentState state) ovveride {
if (auto se = dynamic_cast<SupportedEnvironmentState>) {
// update the state
}
}
};
from navground import core, sim
class MyStateEstimation(sim.PyMyStateEstimation):
# CAN override
# executed at the start of the simulation
# def prepare(self, agent: sim.Agent, world: sim.World) -> None: ...
# CAN override
# executed during the the simulation, should update the state
# update the environment state according to the agent and world
def update(self, agent: sim.Agent, world: sim.World,
state: core.EnvironmentState) -> None:
if isinstance(state, SupportedEnvironmentState):
# update the state
pass
Sensor#
Sensors are a class of state estimation that supports SensingState
(C++
, Python
), which stores data fields (“sensor readings”) in homogenous multi-dimensional arrays.
Sub-class sensor to specialize a state estimation working on SensingState
. In addition to the methods listed above, you must override get_description
(C++
, Python
) to describe the fields that the sensors is going to write (shape, type of data, limits).
Additional virtual methods#
C++ method |
Python method |
override |
---|---|---|
must |
Class skelethon#
#include "navground/sim/sensor.h"
namespace core = navground::core;
namespace sim = navground::sim;
struct MySensor : public sim::Sensor {
// MUST override
// return the description of the data written by the sensor
sim::Sensor::Description get_description() const override {
return {{"my_field", core::BufferDescription(...)}};
};
// CAN override
// executed at the start of the simulation
// void prepare(sim::Agent * agent, sim::World * world) override {
// // call the super class
// sim::Sensor::prepare(agent, world);
// }
// CAN override
// executed during the the simulation
// update the environment state according to the agent and world
void update(sim::Agent *agent, sim::World *world,
core::EnvironmentState state) override {
if (auto se = dynamic_cast<core::SensingState>) {
// compute the data
std::valarray<int> my_data = ...;
// update the sensing state
auto buffer = get_or_init_buffer("my_field");
buffer->set_data(my_data);
}
}
};
import numpy
from navground import core, sim
class MySensor(sim.PySensor):
# MUST override
# return the description of the data written by the sensor
def get_description(self) -> dict[str, core.BufferDescription]:
return {'my_field': core.BufferDescription(...)}
# CAN override
# executed at the start of the simulation
# def prepare(self, agent: sim.Agent, world: sim.World) -> None: ...
# CAN override
# executed during the the simulation, should update the state
# update the environment state according to the agent and world
def update(self, agent: sim.Agent, world: sim.World,
state: core.EnvironmentState) -> None:
if isinstance(state, core.SensingState):
# compute the data
my_data = ...
# update the sensing state
state.set_buffer(key="my_field",
buffer=core.Buffer(data=numpy.asarray(my_data)))