CogniPilot

MODELICA LIBRARY · ENGINEERING REFERENCE

function

SLAM.Simulation.observeLandmarks

Synthetic calibrated RGB-D measurements of a fixed scene

Public declarations

Explicit source declarations; dimensions, modifications and defaults are shown as written, without evaluation.

RoleNameTypeDimensions / attributes / defaultDescription
inputpositionWorld_mReal[3]
inputquaternionWorldBodyReal[4]
inputlandmarksWorld_mReal[:, 3]
inputrotationBodyCameraReal[3, 3]
inputcameraPositionBody_mReal[3]
inputintrinsicsReal[4]fx, fy, cx, cy
inputimageSize_pixelsInteger[2]width, height
inputdepthRange_mReal[2]Minimum and maximum optical-axis depth
inputmeasurementErrorReal[size(landmarksWorld_m, 1), 3]Additive pixel u, pixel v and optical-depth errors
inputdetectedBoolean[size(landmarksWorld_m, 1)]
inputavailableBoolean= true
outputobservationsReal[size(landmarksWorld_m, 1), 3]
outputvisibleBoolean[size(landmarksWorld_m, 1)]

Modelica declarations and implementation

Show parameters, interfaces and source

Parameters, inputs, outputs, defaults and equations from the source file.

function observeLandmarks "Synthetic calibrated RGB-D measurements of a fixed scene"
  input Real positionWorld_m[3];
  input Real quaternionWorldBody[4];
  input Real landmarksWorld_m[:, 3];
  input Real rotationBodyCamera[3, 3];
  input Real cameraPositionBody_m[3];
  input Real intrinsics[4] "fx, fy, cx, cy";
  input Integer imageSize_pixels[2] "width, height";
  input Real depthRange_m[2] "Minimum and maximum optical-axis depth";
  input Real measurementError[size(landmarksWorld_m, 1), 3]
    "Additive pixel u, pixel v and optical-depth errors";
  input Boolean detected[size(landmarksWorld_m, 1)];
  input Boolean available = true;
  output Real observations[size(landmarksWorld_m, 1), 3];
  output Boolean visible[size(landmarksWorld_m, 1)];
protected
  Real rotationWorldBody[3, 3];
  Real rotationCameraWorld[3, 3];
  Real cameraPositionWorld_m[3];
  Real pointCamera_m[3];
  Real projected[3];
  Real measured[3];
  Boolean calibrationValid;
  Boolean pointValid;
algorithm
  rotationWorldBody := LieGroups.SO3.Quat.to_DCM(quaternionWorldBody);
  rotationCameraWorld := transpose(rotationWorldBody * rotationBodyCamera);
  cameraPositionWorld_m := positionWorld_m + rotationWorldBody * cameraPositionBody_m;
  calibrationValid := available and imageSize_pixels[1] > 0 and imageSize_pixels[2] > 0
    and intrinsics[1] > 0.0 and intrinsics[2] > 0.0
    and depthRange_m[1] > 0.0 and depthRange_m[2] > depthRange_m[1]
    and depthRange_m[2] < 1.0e30
    and abs(quaternionWorldBody * quaternionWorldBody - 1.0) < 1.0e-3;
  for component in 1:4 loop
    calibrationValid := calibrationValid and abs(intrinsics[component]) < 1.0e30;
  end for;
  observations := zeros(size(landmarksWorld_m, 1), 3);
  visible := fill(false, size(landmarksWorld_m, 1));
  pointCamera_m := zeros(3);
  projected := zeros(3);
  measured := zeros(3);
  pointValid := false;
  for landmark in 1:size(landmarksWorld_m, 1) loop
    pointCamera_m := rotationCameraWorld * (landmarksWorld_m[landmark, :] - cameraPositionWorld_m);
    pointValid := calibrationValid and detected[landmark]
      and pointCamera_m[3] >= depthRange_m[1] and pointCamera_m[3] <= depthRange_m[2];
    for component in 1:3 loop
      pointValid := pointValid and abs(pointCamera_m[component]) < 1.0e30
        and abs(measurementError[landmark, component]) < 1.0e30;
    end for;
    if pointValid then
      projected := {intrinsics[1] * pointCamera_m[1] / pointCamera_m[3] + intrinsics[3],
        intrinsics[2] * pointCamera_m[2] / pointCamera_m[3] + intrinsics[4], pointCamera_m[3]};
      measured := projected + measurementError[landmark, :];
      visible[landmark] := projected[1] >= 0.0 and projected[1] < imageSize_pixels[1]
        and projected[2] >= 0.0 and projected[2] < imageSize_pixels[2]
        and measured[1] >= 0.0 and measured[1] < imageSize_pixels[1]
        and measured[2] >= 0.0 and measured[2] < imageSize_pixels[2]
        and measured[3] >= depthRange_m[1] and measured[3] <= depthRange_m[2];
      if visible[landmark] then
        observations[landmark, :] := measured;
      end if;
    end if;
  end for;
end observeLandmarks;