Skip to content

Simulation

simulation_attributes

Requirements

Once a map is loaded and a sensor is defined anything is known to simulate the first range data.

// Map
#include <rmagine/map/EmbreeMap.hpp>
// Sensor Models
#include <rmagine/types/sensor_models.h>
// Simulators
#include <rmagine/simulation/SphereSimulatorEmbree.hpp>

namespace rm = rmagine;

// ...

// loading a map
std::string path_to_mesh = "my_mesh.ply";
rm::EmbreeMapPtr map = rm::load_embree_map(path_to_mesh);

// defining a model
rm::SphericalModel velo_model = rm::vlp16_900();

// construct a simulator
rm::SphereSimulatorEmbree sim;
sim.setMap(map);
sim.setModel(velo_model);

// simulate ranges
// ...

Intersection Attributes

Attribute Type Stride Description
Hits uint8 1 If the a face was intersected (1) or not (0)
Ranges float 1 Distance from ray origin along the direction to the first intersection
Points float 3 Cartesian Coordinates of the Intersection (x,y,z)
Normals float 3 Normal (nx, ny, nz) of intersected face
FaceIds uint32 1 The id of the face that was intersected
ObjectIds uint32 1 The id of the object that was intersected
GeomIds uint32 1 The id of the geometry that was intersected

Handle Results

// ...
// Defined previously
// - namespace rm = rmagine;
// - SphereSimulatorEmbree sim;


// 100 Transformations between base and map. e.g. poses of the robot
rm::Memory<rm::Transform, rm::RAM> Tbm(100);

for(size_t i=0; i < Tbm.size(); i++)
{
    rm::Transform T = rm::Transform::Identity();
    T.t = {2.0, 0.0, 0.0}; // position (2,0,0)
    rm::EulerAngles e = {0.0, 0.0, 1.0}; // orientation (0,0,1) radian - as euler angles
    T.R.set(e); // euler internally converted to quaternion
    Tbm[i] = T; // Write Transform/Pose to Memory
}

// add your desired attributes at intersection here
// - optimizes the code at compile time
using ResultT = rm::Bundle<
    rm::Hits<rm::RAM>, 
    rm::Ranges<rm::RAM>
>;

// Possible Attributes (rmagine/simulation/SimulationResults.hpp):
// - Hits
// - Ranges
// - Points
// - Normals
// - FaceIds
// - GeomIds
// - ObjectIds

// querying every attribute with 'rm::IntAttrAny' instead of 'ResultT'

ResultT result = sim.simulate<ResultT>(poses);
// result.hits, result.ranges contain the resulting attribute buffers
std::cout << "printing the first ray's range: " << result.ranges[0] << std::endl;

// or slice the results for the scan of pose 5
auto ranges5 = result.ranges(5 * model.size(), 6 * model.size());
std::cout << "printing the first ray's range of the fifth scan: " << ranges5[0] << std::endl;

// slicing and other useful operations will be described at another Wiki page.

TODO: Explain TF a bit