CogniPilot

MODELICA LIBRARY · ENGINEERING REFERENCE

function

SLAM.PoseGraph.RGBDGraphAnchorBound.FromCapture

Public declarations

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

RoleNameTypeDimensions / attributes / defaultDescription
inputpreviousEstimate
inputcatalogRGBDKeyframes.Catalog
inputledgerRGBDGraphCaptureLedger.State
inputsourceRevisionInteger
inputstepInteger
inputcatalogPoseRevisionInteger
inputanchorPositionReal[dimension]
inputanchorRotationReal[dimension,dimension]
inputprovenanceInteger
inputweightReal= 0.5
inputmaximumPositionShiftReal= 5.0
inputmaximumAngleShiftReal= 0.35
inputrequestedBoolean= true
outputresultEstimate
outputacceptedBoolean
outputreasonInteger

Modelica declarations and implementation

Show parameters, interfaces and source

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

function FromCapture
    input Estimate previous;
    input RGBDKeyframes.Catalog catalog;
    input RGBDGraphCaptureLedger.State ledger;
    input Integer sourceRevision; input Integer step; input Integer catalogPoseRevision;
    input Real anchorPosition[dimension]; input Real anchorRotation[dimension,dimension];
    input Integer provenance;
    input Real weight = 0.5;
    input Real maximumPositionShift = 5.0; input Real maximumAngleShift = 0.35;
    input Boolean requested = true;
    output Estimate result; output Boolean accepted; output Integer reason;
  protected
    Boolean valid; Boolean chartValid; Boolean unchanged;
    Integer id; Integer slot;
    Real offset[poseDimension]; Real J[poseDimension,poseDimension];
    Real attitudeOffset[dimension]; Real angleJacobian[dimension,dimension];
    Real captureBound[poseDimension,poseDimension]; Real candidate[poseDimension,poseDimension];
  algorithm
    result := previous; accepted := false; reason := 1;
    if requested then
      reason := 2;
      valid := RGBDGraphCaptureLedger.Valid(ledger,catalog,sourceRevision,step)
        and catalog.nextId > 1
        and catalogPoseRevision >= 0 and catalogPoseRevision < identifierLimit
        and provenance >= 1 and provenance <= identifierLimit;
      id := 1; slot := 1; unchanged := false;
      if valid then
        id := max(1,catalog.nextId-capacity); slot := mod(id-1,capacity)+1;
        valid := catalog.occupied[slot] and catalog.ids[slot] == id;
      end if;
      if valid then
        reason := 3;
        valid := weight > 0 and weight < 1
          and maximumPositionShift > 0 and maximumPositionShift <= 100
          and maximumAngleShift > 0 and maximumAngleShift <= 0.35;
      end if;
      if valid then
        reason := 4;
        valid := RGBDUncertaintyProper(anchorRotation)
          and RGBDUncertaintyProper(catalog.bodyRotations[slot,:,:]);
        unchanged := true;
        for axis in 1:dimension loop
          valid := valid and abs(anchorPosition[axis]) <= 1e6
            and abs(catalog.bodyPositions[slot,axis]) <= 1e6;
          unchanged := unchanged and anchorPosition[axis] == catalog.bodyPositions[slot,axis];
          for column in 1:dimension loop
            unchanged := unchanged and anchorRotation[axis,column] == catalog.bodyRotations[slot,axis,column];
          end for;
        end for;
        captureBound := catalog.poseCovariances[slot,:,:];
        valid := valid and SLAMCovariancePSDCheck(captureBound,1e-12) == 1;
      end if;
      if valid then
        candidate := captureBound;
        if not unchanged then
          reason := 5;
          offset := zeros(poseDimension);
          offset[1:dimension] := catalog.bodyPositions[slot,:]-anchorPosition;
          (attitudeOffset,chartValid) := SchmidtGraphPoseCorrection.Log(
            transpose(anchorRotation)*catalog.bodyRotations[slot,:,:]);
          valid := chartValid and sqrt(offset[1:dimension]*offset[1:dimension]) <= maximumPositionShift
            and sqrt(attitudeOffset*attitudeOffset) <= maximumAngleShift;
          if valid then
            offset[dimension+1:poseDimension] := attitudeOffset;
            J := identity(poseDimension);
            angleJacobian := SchmidtGraphPoseCorrection.InverseJacobian(attitudeOffset,true);
            J[dimension+1:poseDimension,dimension+1:poseDimension] := angleJacobian;
            // If e_new = offset+J*e_capture to first order and E[e e']<=P,
            // weighted Young bounds its SECOND MOMENT even for unknown mean.
            candidate := J*captureBound*transpose(J)/weight
              +outerProduct(offset,offset)/(1-weight);
          end if;
        end if;
        if valid then
          reason := 6; valid := SLAMCovariancePSDCheck(candidate,1e-12) == 1;
          if valid then
            result.binding.generation := catalog.generation;
            result.binding.sourceRevision := sourceRevision; result.binding.id := id; result.binding.slot := slot;
            result.binding.epoch := catalog.epochs[slot]; result.binding.sequence := ledger.sequences[slot];
            result.binding.catalogPoseRevision := catalogPoseRevision;
            result.binding.provenance := provenance; result.binding.imageTime := catalog.imageTimes[slot];
            result.position := anchorPosition; result.rotation := anchorRotation; result.bound := candidate;
            accepted := true; reason := 0;
          end if;
        end if;
      end if;
    end if;
  end FromCapture;