block
SLAM.Simulation.LandmarkCamera
Landmark-level RGB-D camera with explicit visibility and errors
Sampled pinhole RGB-D camera. Supply a fixed landmark scene, true world-ENU position and unit body-to-world quaternion. The default optical axis points downward for a level FLU body.
Geometry
Configure horizontal/vertical fieldOfView_rad,
imageSize_pixels and optical-axis depthRange_m.
Default focal lengths are width/(2 tan(horizontalFov/2)) and
height/(2 tan(verticalFov/2)); measured intrinsics may override
them. rotationBodyCamera maps optical-camera vectors to body
FLU; cameraPositionBody_m is the lever arm.
Observations and visibility
Each observation row is {pixel u, pixel v, optical depth in metres}.
Both ideal and noisy observations must lie inside the image's half-open
bounds and inclusive depth range. visible is authoritative:
invisible rows contain zeros and must not be fused. landmarkIds
are stable row indices; preserve an external feature-ID mapping if rows
from a captured map are reordered.
Supply additive measurementError explicitly to share noise
across experiments. The caller owns its covariance and timestamps.
detected supplies per-row dropout; available
disables the camera. The model does not infer occlusion, distortion,
rolling shutter or association ambiguity.
Example
SLAM.Simulation.LandmarkCamera camera(
landmarkCount=4,
landmarksWorld_m=SLAM.Simulation.landmarkGrid(2, 2, 2.0),
positionWorld_m=truthPositionWorld_m,
quaternionWorldBody=truthQuaternionWorldBody,
fieldOfView_rad={1.4, 1.0}, depthRange_m={0.2, 8.0});
Public declarations
Explicit source declarations; dimensions, modifications and defaults are shown as written, without evaluation.
| Role | Name | Type | Dimensions / attributes / default | Description |
|---|---|---|---|---|
| parameter | landmarkCount | Integer | (min=1) = 12 | |
| input | landmarksWorld_m | Real | [landmarkCount, 3] = landmarkGrid(3, 4, 0.75) | Fixed scene truth; may be supplied from an independently initialized map |
| parameter | cameraRate_Hz | Real | (min=1.0e-6) = 10.0 | |
| parameter | fieldOfView_rad | Real | [2] = {2.0 * atan(640.0 / 700.0), 2.0 * atan(480.0 / 700.0)} | |
| input | intrinsics | Real | [4] = {imageSize_pixels[1] / (2.0 * tan(0.5 * fieldOfView_rad[1])),
imageSize_pixels[2] / (2.0 * tan(0.5 * fieldOfView_rad[2])),
0.5 * imageSize_pixels[1], 0.5 * imageSize_pixels[2]} | |
| input | imageSize_pixels | Integer | [2] = {640, 480} | |
| input | depthRange_m | Real | [2] = {0.1, 10.0} | |
| input | rotationBodyCamera | Real | [3, 3] = [1.0, 0.0, 0.0; 0.0, -1.0, 0.0; 0.0, 0.0, -1.0] | |
| input | cameraPositionBody_m | Real | [3] = zeros(3) | |
| input | positionWorld_m | Real | [3] | |
| input | quaternionWorldBody | Real | [4] | |
| input | measurementError | Real | [landmarkCount, 3] = zeros(landmarkCount, 3) | |
| input | detected | Boolean | [landmarkCount] = fill(true, landmarkCount) | |
| input | available | Boolean | = true | |
| output | landmarkIds | Integer | [landmarkCount] = 1:landmarkCount | |
| output | observations | Real | [landmarkCount, 3] | |
| output | visible | Boolean | [landmarkCount] |
Modelica declarations and implementation
Show parameters, interfaces and source
Parameters, inputs, outputs, defaults and equations from the source file.
block LandmarkCamera "Landmark-level RGB-D camera with explicit visibility and errors"
parameter Integer landmarkCount(min=1) = 12;
input Real landmarksWorld_m[landmarkCount, 3] = landmarkGrid(3, 4, 0.75)
"Fixed scene truth; may be supplied from an independently initialized map";
parameter Real cameraRate_Hz(min=1.0e-6) = 10.0;
parameter Real fieldOfView_rad[2] = {2.0 * atan(640.0 / 700.0), 2.0 * atan(480.0 / 700.0)};
input Real intrinsics[4] = {imageSize_pixels[1] / (2.0 * tan(0.5 * fieldOfView_rad[1])),
imageSize_pixels[2] / (2.0 * tan(0.5 * fieldOfView_rad[2])),
0.5 * imageSize_pixels[1], 0.5 * imageSize_pixels[2]};
input Integer imageSize_pixels[2] = {640, 480};
input Real depthRange_m[2] = {0.1, 10.0};
input Real rotationBodyCamera[3, 3] = [1.0, 0.0, 0.0; 0.0, -1.0, 0.0; 0.0, 0.0, -1.0];
input Real cameraPositionBody_m[3] = zeros(3);
input Real positionWorld_m[3];
input Real quaternionWorldBody[4];
input Real measurementError[landmarkCount, 3] = zeros(landmarkCount, 3);
input Boolean detected[landmarkCount] = fill(true, landmarkCount);
input Boolean available = true;
output Integer landmarkIds[landmarkCount] = 1:landmarkCount;
output Real observations[landmarkCount, 3];
output Boolean visible[landmarkCount];
algorithm
when sample(0.0, 1.0 / cameraRate_Hz) then
(observations, visible) := observeLandmarks(positionWorld_m, quaternionWorldBody,
landmarksWorld_m, rotationBodyCamera, cameraPositionBody_m, intrinsics,
imageSize_pixels, depthRange_m, measurementError, detected, available);
end when;
annotation(Documentation(info = "<html>
<p>Sampled pinhole RGB-D camera. Supply a fixed landmark scene, true
world-ENU position and unit body-to-world quaternion. The default optical
axis points downward for a level FLU body.</p>
<h4>Geometry</h4>
<p>Configure horizontal/vertical <code>fieldOfView_rad</code>,
<code>imageSize_pixels</code> and optical-axis <code>depthRange_m</code>.
Default focal lengths are width/(2 tan(horizontalFov/2)) and
height/(2 tan(verticalFov/2)); measured <code>intrinsics</code> may override
them. <code>rotationBodyCamera</code> maps optical-camera vectors to body
FLU; <code>cameraPositionBody_m</code> is the lever arm.</p>
<h4>Observations and visibility</h4>
<p>Each observation row is {pixel u, pixel v, optical depth in metres}.
Both ideal and noisy observations must lie inside the image's half-open
bounds and inclusive depth range. <code>visible</code> is authoritative:
invisible rows contain zeros and must not be fused. <code>landmarkIds</code>
are stable row indices; preserve an external feature-ID mapping if rows
from a captured map are reordered.</p>
<p>Supply additive <code>measurementError</code> explicitly to share noise
across experiments. The caller owns its covariance and timestamps.
<code>detected</code> supplies per-row dropout; <code>available</code>
disables the camera. The model does not infer occlusion, distortion,
rolling shutter or association ambiguity.</p>
<h4>Example</h4>
<pre>
SLAM.Simulation.LandmarkCamera camera(
landmarkCount=4,
landmarksWorld_m=SLAM.Simulation.landmarkGrid(2, 2, 2.0),
positionWorld_m=truthPositionWorld_m,
quaternionWorldBody=truthQuaternionWorldBody,
fieldOfView_rad={1.4, 1.0}, depthRange_m={0.2, 8.0});
</pre>
</html>"));
end LandmarkCamera;