Skip to content

AcresEpisodeLog.h#

Acres/Source/Acres/AcresEpisodeLog.h Generated

The episode log: an MCAP file of ROS 2 messages (CDR) with every agent's state at the physics rate, the farm events, conditions, hardware shifts and the episode clock (Documentation/Reference/episode-log.md). Pure C++17, no Unreal types and no ROS: the game (AcresSimControl.cpp) writes and replays it, ACRES Core compiles the same file, and Tools/EpisodeLog/build.sh tests it. The message layouts mirror ROS/acres_interfaces/msg; the schema texts are generated into AcresEpisodeSchemas.h (Tools/EpisodeLog/gen_schemas.py).

Formats: - CDR: the ROS 2 wire format, little-endian, a 4-byte encapsulation header (0, 1, 0, 0), every primitive aligned to its size from the end of that header, strings as a uint32 length with the terminating NUL, sequences as a uint32 count (their first element aligned only when there is one), fixed arrays without a count. - MCAP (https://mcap.dev/spec, version 0): magic, header, data section (schemas and channels as they are first used, metadata, uncompressed chunks of about 1 MB, each followed by its message indexes and flushed to disk), data end, summary (schemas, channels, statistics, chunk indexes, metadata index), summary offsets, footer, magic. CRC-32 on chunks, the data section and the summary.

Example

AcresLog::FEpisodeWriter Log;
std::string Error;
if (Log.Open("/tmp/episode.mcap", {{"source", "unreal"}}, Error))
{
    AcresLog::FAgentStates States;
    States.Stamp = AcresLog::FTime::FromSeconds(1.25);
    Log.Write(States);
    Log.Close();
}

Encode#

A message as CDR bytes (with the encapsulation header).

template <class T> std::vector<uint8_t> Encode(const T& Message) ;

Decode#

Decodes CDR bytes into Message; false if they are too short or not little-endian CDR.

template <class T> bool Decode(const uint8_t* Data, size_t Size, T& Message) ;

Crc32#

CRC-32 (IEEE 802.3, as zlib), continuing from Crc (0 to start).

uint32_t Crc32(const void* Data, size_t Size, uint32_t Crc = 0);

ReadMcap#

Reads every message of an MCAP file in file order (unchunked messages and uncompressed chunks; compressed chunks are an error) and its metadata records.

Argument Description
Path The file.
OnMessage Called for each message, in file order.
Metadata Receives every metadata record (name -> map), may be null.
Error Set on failure.

Returns: False if the file is missing, not MCAP, truncated before any data or uses compression.

bool ReadMcap(const std::string& Path, const std::function<void(const FMcapMessage&)>& OnMessage, std::map<std::string, std::map<std::string, std::string>>* Metadata, std::string& Error);

FTime#

struct FTime

builtin_interfaces/Time.

Name Type Unit Default Description
Sec int32_t 0 Sec: whole seconds. Nanosec: 0..999999999.

FTime::FromSeconds#

Time from seconds (rounded to the nanosecond).

static FTime FromSeconds(double Seconds);

FTime::Seconds#

Seconds as a double.

double Seconds() const ;

FTime::Nanoseconds#

Nanoseconds since zero (the MCAP log time).

uint64_t Nanoseconds() const ;

FVec3#

struct FVec3

geometry_msgs/Vector3 (and Point).

FQuat4#

struct FQuat4

geometry_msgs/Quaternion, xyzw.

FPose#

struct FPose

geometry_msgs/Pose.

FTwist#

struct FTwist

geometry_msgs/Twist.

FEpisode#

struct FEpisode

acres_interfaces/msg/Episode (topic /sim/episode).

Name Type Unit Default Description
Stamp FTime Stamp: simulation time; FrameId: empty.
EpisodeId std::string See Episode.msg for every field.

FAgentInfo#

struct FAgentInfo

acres_interfaces/msg/AgentInfo.

Name Type Unit Default Description
BodyOriginFluM FVec3 m Body origin in base_footprint (FLU), m.

FAgents#

struct FAgents

acres_interfaces/msg/Agents (topic /sim/agents).

FEnergyLedger#

struct FEnergyLedger

acres_interfaces/msg/EnergyLedger: cumulative energies since the agent's reset, J (AcresPowerModel.h).

Name Type Unit Default Description
GroundLoss double 0 GroundLoss: Slip + Lateral + Soil, the energy the ground took.

FAgentState#

struct FAgentState

acres_interfaces/msg/AgentState: one agent after one physics step. Pose: base_footprint in the world frame (grid ENU, m); twist in the body frame (FLU). See AgentState.msg for every field.

Name Type Unit Default Description
WheelContact std::array&lt;bool, 4> Per wheel: ground contact; surface class (AcresSurfaceMap.h ESurfaceClass); field id (0 outside fields).

FAgentStates#

struct FAgentStates

acres_interfaces/msg/AgentStates (topic /sim/agent_states, every physics step).

FFarmEvent#

struct FFarmEvent

acres_interfaces/msg/FarmEvent. Kind: CropCrushed .. FieldRestored.

Name Type Unit Default Description
X double 0 See above.
Y double 0 World east, north, m.
Value double 0 Area m2 (crop, worked) or rut depth m.

FFarmEvents#

struct FFarmEvents

acres_interfaces/msg/FarmEvents (topic /sim/farm_events).

FFarmStamp#

struct FFarmStamp

acres_interfaces/msg/FarmStamp: the arguments of one FAcresFarmRuntime::Wheel (Kind 0) or Body (Kind 1) call.

Name Type Unit Default Description
X, Y, Z, ForwardX, ForwardY, WidthM, LengthM, PressurePa, SinkageM, TyreDiameterM, ClearanceM, CrushedM2 double World ENU m; unit heading; footprint m; pressure Pa; sinkage m; tyre diameter m; body clearance m; crushed m2.

FFarmStamps#

struct FFarmStamps

acres_interfaces/msg/FarmStamps (topic /sim/farm_stamps).

FConditions#

struct FConditions

acres_interfaces/msg/Conditions (topic /sim/conditions).

FVehicleShift#

struct FVehicleShift

acres_interfaces/msg/VehicleShift: offsets on the actuators and sensor mounts (see VehicleShift.msg).

FVehicleShifts#

struct FVehicleShifts

acres_interfaces/msg/VehicleShifts (topic /sim/shifts).

FTaskStatus#

struct FTaskStatus

acres_interfaces/msg/TaskStatus (topic /sim/task; written by learners).

FCdrWriter#

class FCdrWriter

CDR serializer (see the file comment). Call a message's Visit with it, or use Encode.

Name Type Unit Default Description
class template &lt;class T, Nested messages (anything with Visit).

FCdrWriter::Bytes#

The bytes written so far, encapsulation header included.

const std::vector<uint8_t>& Bytes() const ;

FCdrReader#

class FCdrReader

CDR deserializer. Ok() turns false at the first read past the end (the rest reads zeros).

FCdrReader::FCdrReader#

Reads Size bytes at Data (the encapsulation header included; big-endian data is refused).

FCdrReader(const uint8_t* Data, size_t Size);

FCdrReader::Ok#

False after a read ran past the end or the header was not little-endian CDR.

bool Ok() const ;

FMcapWriter#

class FMcapWriter

Minimal MCAP writer: uncompressed chunks with message indexes, a full summary section.

Name Type Unit Default Description
ChunkBytes size_t 1u &lt;&lt; 20 Chunk size at which a chunk is written (and the file flushed), bytes of records: what a crash can lose.

FMcapWriter::Open#

Creates the file and writes the magic and header record.

Argument Description
Path Output file (replaced).
Profile MCAP profile ("ros2").
Library Writer name for the header.
Error Set on failure.
bool Open(const std::string& Path, const std::string& Profile, const std::string& Library, std::string& Error);

FMcapWriter::AddSchema#

Registers a schema; returns its id (1..).

uint16_t AddSchema(const std::string& Name, const std::string& Encoding, const std::string& Data);

FMcapWriter::AddChannel#

Registers a channel on a schema; returns its id (0..).

uint16_t AddChannel(const std::string& Topic, uint16_t SchemaId, const std::string& MessageEncoding, const std::map<std::string, std::string>& Metadata = ;);

FMcapWriter::Write#

Adds one message to the current chunk (a full chunk is written first).

Argument Description
Channel A channel id from AddChannel. LogTimeNs, PublishTimeNs: Times, ns. Data, Size: The serialized message.
void Write(uint16_t Channel, uint64_t LogTimeNs, uint64_t PublishTimeNs, const uint8_t* Data, size_t Size);

FMcapWriter::Metadata#

Writes a metadata record (name and string map).

void Metadata(const std::string& Name, const std::map<std::string, std::string>& Values);

FMcapWriter::Close#

Writes the last chunk, the summary and the footer, and closes the file. Safe to call twice.

bool Close();

FMcapWriter::IsOpen#

True between Open and Close.

bool IsOpen() const ;

FMcapWriter::MessageCount#

Messages written so far.

uint64_t MessageCount() const ;

FMcapMessage#

struct FMcapMessage

One message read from an MCAP file.

Name Type Unit Default Description
Topic, Schema std::string Topic and schema name of its channel, its log time (ns) and the serialized data.

FEpisodeWriter#

class FEpisodeWriter

The episode log writer: an FMcapWriter with the ACRES topics registered (ros2 profile, CDR, the generated schema texts) and one typed Write per message.

Name Type Unit Default Description
EpisodeTopic static constexpr const char* "/sim/episode" Topics of the episode log.
FirstS, LastS double Log time of the first and last message written, s (0 before any).

FEpisodeWriter::Open#

Opens the file, registers the topics and writes the acres_episode metadata record (Values: its keys, see episode-log.md; schema_version is added).

bool Open(const std::string& Path, const std::map<std::string, std::string>& Values, std::string& Error);

FEpisodeWriter::AddTopic#

Registers a further topic, for messages the ACRES topics do not carry (the ds_dbw_msgs commands as the vehicle received them, which ACRES Core writes); readers that do not know it skip it.

Argument Description
Topic The topic, e.g. "/polaris/vehicle/steering/cmd".
SchemaName Its ROS 2 type, e.g. "ds_dbw_msgs/msg/SteeringCmd".
SchemaText The type's ros2msg definition with its dependencies, as rosbag2 writes it.

Returns: The channel for WriteRaw.

uint16_t AddTopic(const std::string& Topic, const std::string& SchemaName, const std::string& SchemaText);

FEpisodeWriter::WriteRaw#

Writes one CDR message (with its encapsulation header) on a topic of AddTopic, at its stamp.

void WriteRaw(uint16_t Channel, const FTime& Stamp, const std::vector<uint8_t>& Bytes) ;

FEpisodeWriter::Close#

Finishes the file.

bool Close() ;

FEpisodeLog#

struct FEpisodeLog

A whole episode log read back (for replay and tests): every message decoded, in file order per topic.

FEpisodeLog::Load#

Reads Path; false with Error on a read or decode failure.

bool Load(const std::string& Path, std::string& Error);