CogniPilot

MODELICA LIBRARY · ENGINEERING REFERENCE

SLAM/Mapping/RGBDProjectLandmarks.mo

Download original .moGitHub source

Documentation: SLAM.Mapping.RGBDProjectLandmarks

within SLAM.Mapping;
// Source-owned reusable projection; the unchanged equation model is its oracle.
// Counts and masks retain the model's exact Real-domain checks. Disabled or
// unavailable point payloads never enter transforms. World-output overflow is
// excluded from validCount but is not an optical-input invalidCount event.
function RGBDProjectLandmarks
  import RGBDLandmarkRotationValid = SLAM.Mapping.RGBDLandmarkRotationValid;

  input Real opticalPoint[:,3];
  input Real enabled[size(opticalPoint,1)];
  input Real activeCount = 0.0;
  input Real poseAccepted = 0.0;
  input Real bodyRotation[3,3] = identity(3);
  input Real bodyPosition[3] = zeros(3);
  input Real opticalToBody[3,3] = [0.0,0.0,1.0;-1.0,0.0,0.0;0.0,-1.0,0.0];
  input Real cameraOriginBody[3] = {0.18,0.0,-0.04};
  input Real coordinateLimit = 1e6;
  output Real worldPoint[size(opticalPoint,1),3];
  output Real landmarkEnabled[size(opticalPoint,1)];
  output Real validCount;
  output Real invalidCount;
  output Real configurationValid;
  output Real poseValid;
protected
  Real bodyValid; Real cameraValid; Real poseChecks;
  Real pointChecks; Real pointValid; Real outputChecks;
  Real cameraInBody[3]; Real proposedWorld[3];
algorithm
  worldPoint := zeros(size(opticalPoint,1),3);
  landmarkEnabled := zeros(size(opticalPoint,1)); validCount := 0.0; invalidCount := 0.0;
  configurationValid := if activeCount >= 0.0 and activeCount <= size(opticalPoint,1)
    and floor(activeCount) <= activeCount and floor(activeCount) >= activeCount
    and coordinateLimit > 0.0 and coordinateLimit <= 1e6 then 1.0 else 0.0;
  bodyValid := RGBDLandmarkRotationValid(bodyRotation);
  cameraValid := RGBDLandmarkRotationValid(opticalToBody);
  poseChecks := 0.0;
  for k in 1:3 loop
    if not (abs(bodyPosition[k]) <= coordinateLimit and abs(cameraOriginBody[k]) <= coordinateLimit) then
      poseChecks := poseChecks+1.0;
    end if;
  end for;
  poseValid := if configurationValid > 0.5 and poseAccepted >= 1.0 and poseAccepted <= 1.0
    and bodyValid > 0.5 and cameraValid > 0.5 and poseChecks < 0.5 then 1.0 else 0.0;
  pointChecks := 0.0; pointValid := 0.0; outputChecks := 0.0;
  cameraInBody := zeros(3); proposedWorld := zeros(3);
  for i in 1:size(opticalPoint,1) loop
    pointChecks := 0.0;
    for k in 1:3 loop
      if not (abs(opticalPoint[i,k]) <= coordinateLimit) then pointChecks := pointChecks+1.0; end if;
    end for;
    pointValid := if configurationValid > 0.5 and i <= activeCount
      and enabled[i] >= 1.0 and enabled[i] <= 1.0 and pointChecks < 0.5
      and opticalPoint[i,3] > 0.0 then 1.0 else 0.0;
    if i <= activeCount and not (enabled[i] >= 0.0 and enabled[i] <= 0.0)
      and pointValid < 0.5 then invalidCount := invalidCount+1.0; end if;
    if poseValid > 0.5 and pointValid > 0.5 then
      cameraInBody := opticalToBody*opticalPoint[i,:]+cameraOriginBody;
      proposedWorld := bodyRotation*cameraInBody+bodyPosition;
      outputChecks := 0.0;
      for k in 1:3 loop
        if not (abs(proposedWorld[k]) <= coordinateLimit) then outputChecks := outputChecks+1.0; end if;
      end for;
      if outputChecks < 0.5 then
        worldPoint[i,:] := proposedWorld; landmarkEnabled[i] := 1.0; validCount := validCount+1.0;
      end if;
    end if;
  end for;
end RGBDProjectLandmarks;