SLAM/Mapping/RGBDLandmarkProjection.mo
Download original .moGitHub source
Documentation: SLAM.Mapping.RGBDLandmarkProjection
within SLAM.Mapping;
// Candidate coordinates only: no map persistence, pruning or SLAM lifecycle.
// Points are already calibrated optical RDF (right/down/forward). The supplied
// estimated body pose maps body FLU into world ENU; there is no truth input.
model RGBDLandmarkProjection
import RGBDLandmarkRotationCheck = SLAM.Mapping.RGBDLandmarkRotationCheck;
constant Integer featureCapacity = 350;
constant Integer dimension = 3;
parameter Real coordinateLimit = 1e6;
input Real opticalPoint[featureCapacity,dimension];
input Real enabled[featureCapacity];
input Real activeCount = 0.0;
input Real poseAccepted = 0.0;
input Real bodyRotation[dimension,dimension] = identity(dimension);
input Real bodyPosition[dimension] = zeros(dimension);
input Real opticalToBody[dimension,dimension] = [0.0,0.0,1.0;-1.0,0.0,0.0;0.0,-1.0,0.0];
input Real cameraOriginBody[dimension] = {0.18,0.0,-0.04};
output Real worldPoint[featureCapacity,dimension];
output Real landmarkEnabled[featureCapacity];
output Real validCount;
output Real invalidCount;
output Real configurationValid;
output Real poseValid;
protected
RGBDLandmarkRotationCheck bodyCheck(rotation=bodyRotation);
RGBDLandmarkRotationCheck cameraCheck(rotation=opticalToBody);
Real poseChecks[dimension];
Real pointChecks[featureCapacity,dimension];
Real pointValid[featureCapacity];
Real invalidChecks[featureCapacity];
Real safeOptical[featureCapacity,dimension];
Real safeBodyRotation[dimension,dimension];
Real safeOpticalToBody[dimension,dimension];
Real safeBodyPosition[dimension];
Real safeCameraOrigin[dimension];
Real cameraInBody[featureCapacity,dimension];
Real proposedWorld[featureCapacity,dimension];
Real outputChecks[featureCapacity,dimension];
equation
configurationValid = if noEvent(activeCount >= 0.0 and activeCount <= featureCapacity
and floor(activeCount) <= activeCount and floor(activeCount) >= activeCount
and coordinateLimit > 0.0 and coordinateLimit <= 1e6) then 1.0 else 0.0;
for k in 1:dimension loop
poseChecks[k] = if noEvent(abs(bodyPosition[k]) <= coordinateLimit
and abs(cameraOriginBody[k]) <= coordinateLimit) then 0.0 else 1.0;
end for;
poseValid = if noEvent(configurationValid > 0.5 and poseAccepted >= 1.0 and poseAccepted <= 1.0
and bodyCheck.valid > 0.5 and cameraCheck.valid > 0.5 and sum(poseChecks) < 0.5) then 1.0 else 0.0;
safeBodyRotation = if noEvent(poseValid > 0.5) then bodyRotation else identity(dimension);
safeOpticalToBody = if noEvent(poseValid > 0.5) then opticalToBody else identity(dimension);
safeBodyPosition = if noEvent(poseValid > 0.5) then bodyPosition else zeros(dimension);
safeCameraOrigin = if noEvent(poseValid > 0.5) then cameraOriginBody else zeros(dimension);
for i in 1:featureCapacity loop
for k in 1:dimension loop
pointChecks[i,k] = if noEvent(abs(opticalPoint[i,k]) <= coordinateLimit) then 0.0 else 1.0;
safeOptical[i,k] = if noEvent(poseValid > 0.5 and pointValid[i] > 0.5) then opticalPoint[i,k] else 0.0;
outputChecks[i,k] = if noEvent(abs(proposedWorld[i,k]) <= coordinateLimit) then 0.0 else 1.0;
worldPoint[i,k] = if noEvent(landmarkEnabled[i] > 0.5) then proposedWorld[i,k] else 0.0;
end for;
pointValid[i] = if noEvent(configurationValid > 0.5 and i <= activeCount
and enabled[i] >= 1.0 and enabled[i] <= 1.0 and sum(pointChecks[i,:]) < 0.5
and opticalPoint[i,3] > 0.0) then 1.0 else 0.0;
cameraInBody[i,:] = safeOpticalToBody*safeOptical[i,:]+safeCameraOrigin;
proposedWorld[i,:] = safeBodyRotation*cameraInBody[i,:]+safeBodyPosition;
landmarkEnabled[i] = if noEvent(poseValid > 0.5 and pointValid[i] > 0.5
and sum(outputChecks[i,:]) < 0.5) then 1.0 else 0.0;
invalidChecks[i] = if noEvent(i <= activeCount and not (enabled[i] >= 0.0 and enabled[i] <= 0.0)
and pointValid[i] < 0.5) then 1.0 else 0.0;
end for;
validCount = sum(landmarkEnabled);
invalidCount = sum(invalidChecks);
end RGBDLandmarkProjection;