<ServerManagerConfiguration>
  <!-- Begin Online Slam -->
  <ProxyGroup name="filters">
    <SourceProxy name="Slam (Online)" class="vtkSlam" label="Slam (Online)">
      <Documentation
        short_help="Performs SLAM algorithm based on lidar sensor outputted point cloud"
        long_help="Performs SLAM algorithm based on lidar sensor outputted point cloud.
                   The SLAM algorithm is composed of three sequential steps:
                   - Sampling strategy: extract keypoints that provide strong geometric information
                   - Ego Motion: Sensor motion estimation between two frames
                   - Mapping: Map the frame in a environment map">
        filter which performs slam on points data.
      </Documentation>

      <InputProperty
         name="PointCloud"
         port_index="0"
         command="SetInputConnection">
        <DataTypeDomain name="input_type">
          <DataType value="vtkPolyData"/>
        </DataTypeDomain>
        <Documentation>
          Set the input trajectory
        </Documentation>
      </InputProperty>

      <InputProperty
         name="Calibration"
         port_index="1"
         command="SetInputConnection">
        <DataTypeDomain name="input_type">
          <DataType value="vtkTable"/>
        </DataTypeDomain>
        <Documentation>
          Set the input point cloud
        </Documentation>
      </InputProperty>

      <OutputPort name="Last Frame processed" index="0" id="port0" />
      <OutputPort name="Trajectory" index="1" id="port1" />
      <OutputPort name="Edge   Map" index="2" id="port2" />
      <OutputPort name="Planar Map" index="3" id="port3" />
      <OutputPort name="Blob   Map" index="4" id="port4" />

      <!-- ==================== General ==================== -->
      <IntVectorProperty
          name="Fast Slam"
          command="SetFastSlam"
          default_values="1"
          number_of_elements="1">
        <BooleanDomain name="bool" />
        <Documentation>
          If fast slam is enable we remove the extraction of
          blobs point in the Keypoint extraction step
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="Display Mode"
          command="SetDisplayMode"
          default_values="1"
          number_of_elements="1">
        <BooleanDomain name="bool" />
        <Documentation>
          If set display mode is enable, some extra arrays area
          added to the SLAM output to display the SLAM algorithm
          internal variables (the keypoints labels, the value of the
          computed geometric features, ...). It is very usefull when
          debugging and improving the SLAM
        </Documentation>
      </IntVectorProperty>

<!--      <IntVectorProperty
          name="Undistortion Model"
          command="SetUndistortion"
          default_values="0"
          number_of_elements="1">
        <BooleanDomain name="bool" />
        <Documentation>
          If undistortion model is enabled, the SLAM will use a motion
          model to undistorded the acquired frame during a sweep of the
          lidar. If it is not enabled, the slam will compute a rigid
          transform that will be applied to the all frame without taking
          into acocunt the distortion due to the liadr motion during a sweep
        </Documentation>
      </IntVectorProperty>-->

      <PropertyGroup label="General Parameters">
        <Property name="Display Mode" />
        <Property name="Fast Slam" />
<!--        <Property name="Undistortion Model" />-->
      </PropertyGroup>

      <ProxyProperty
        name="KeyPointsExtractor"
        command="SetKeyPointsExtractor"
        label="KeyPointsExtractor">
        <ProxyListDomain name="proxy_list">
          <Group name="KeyPointsExtractor"/>
        </ProxyListDomain>
      </ProxyProperty>
      <!-- ==================== Ego Motion Parameters ==================== -->
      <IntVectorProperty
          name="Lev-Mardt Maximum Iteration"
          command="SetEgoMotionLMMaxIter"
          default_values="15"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          The sensor motion estimation is performed using an ICP Mahalanobis
          distance function. This lead to a numerical optimization problem with a
          non-linear least square cost function (with a loss-function). To solve this
          optimization problem we use the Levenberg-Marquardt algorithm which is an iterative
          algorithm.
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="ICP Maximum Itertation"
          command="SetEgoMotionICPMaxIter"
          default_values="4"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          The sensor motion estimation is performed using an ICP Mahalanobis
          distance function. The ICP algorithm is an iterative algorithm and the number
          of iteration has to be settled
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="# Edges Neighbors Minimum After Ransac"
          command="SetEgoMotionMinimumLineNeighborRejection"
          default_values="3"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          In the Ego-Motion step, the neighborhood of an edge keypoint
          is fitted using a ransac algorithm. This parameter settled the
          minimum number of inlier we want to consider the point
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="# Edge Neighbors"
          command="SetEgoMotionLineDistanceNbrNeighbors"
          default_values="8"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          K-nearest neighbors point to consider to compute the Variance-Covariance
          matrix of the neighborhood to define the Mahalanobis distance function.
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="# Plane Neighbors"
          command="SetEgoMotionPlaneDistanceNbrNeighbors"
          default_values="5"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          K-nearest neighbors points to consider to compute the Variance-Covariance
          matrix of the neighborhood to define the Mahalanobis distance function.
        </Documentation>
      </IntVectorProperty>

      <DoubleVectorProperty
          name="Linearity Factor #1"
          command="SetEgoMotionLineDistancefactor"
          default_values="5"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject an edge keypoint if its neighborhood is not distributed
          along a line eigenvalue1 > Factor * eigenvalue2
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Planarity Factor #1"
          command="SetEgoMotionPlaneDistancefactor1"
          default_values="35"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject a planar keypoint if its neighborhood is not distributed
          along a plane: Factor1 * eigenvalue2 > eigenvalue1 and
          eigenvalue2 > Factor2 * eigenvalue3
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Planarity Factor #2"
          command="SetEgoMotionPlaneDistancefactor2"
          default_values="8"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject a planar keypoint if its neighborhood is not distributed
          along a plane: Factor1 * eigenvalue2 > eigenvalue1 and
          eigenvalue2 > Factor2 * eigenvalue3
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Max Edge-Neighbors Distance To Fitted Line"
          command="SetEgoMotionMaxLineDistance"
          default_values="0.2"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject an edge point if its neighborhood has points that
          are too far from the fitted line (degenerated ellipsoid)
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Max Plane-Neighbors Distance To Fitted Plane"
          command="SetEgoMotionMaxPlaneDistance"
          default_values="0.2"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject a planar point if its neighborhood has points that
          are too far from the fitted plane (degenerated ellipsoid)
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Ego Motion Init Loss Scale"
          command="SetEgoMotionInitLossScale"
          default_values="2.0"
          number_of_elements="1"
          panel_visibility="advanced">
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Ego Motion Final Loss Scale"
          command="SetEgoMotionFinalLossScale"
          default_values="0.2"
          number_of_elements="1"
          panel_visibility="advanced">
      </DoubleVectorProperty>

      <PropertyGroup label="Ego-Motion ICP Matching And Optimization Parameters">
        <Property name="Lev-Mardt Maximum Iteration" />
        <Property name="ICP Maximum Itertation" />
        <Property name="# Edges Neighbors Minimum After Ransac" />
        <Property name="# Edge Neighbors" />
        <Property name="# Plane Neighbors" />
        <Property name="Linearity Factor #1" />
        <Property name="Planarity Factor #1" />
        <Property name="Planarity Factor #2" />
        <Property name="Max Edge-Neighbors Distance To Fitted Line" />
        <Property name="Max Plane-Neighbors Distance To Fitted Plane" />
        <Property name="Ego Motion Init Loss Scale" />
        <Property  name="Ego Motion Final Loss Scale" />
     </PropertyGroup>

     <!-- ==================== Mapping Parameters ==================== -->
     <IntVectorProperty
          name="Lev-Mardt Maximum Iteration M"
          command="SetMappingLMMaxIter"
          default_values="15"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          The sensor motion estimation is performed using an ICP Mahalanobis
          distance function. This lead to a numerical optimization problem with a
          non-linear least square cost function (with a loss-function). To solve this
          optimization problem we use the Levenberg-Marquardt algorithm which is an iterative
          algorithm.
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="ICP Maximum Itertation M"
          command="SetMappingICPMaxIter"
          default_values="3"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          The sensor motion estimation is performed using an ICP Mahalanobis
          distance function. The ICP algorithm is an iterative algorithm and the number
          of iteration has to be settled
        </Documentation>
      </IntVectorProperty>

     <IntVectorProperty
          name="# Edges Neighbors Minimum After Ransac M"
          command="SetMappingMinimumLineNeighborRejection"
          default_values="4"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          In the Mapping step, the neighborhood of an edge keypoint
          is fitted using a ransac algorithm. This parameter settled the
          minimum number of inlier we want to consider the point
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="# Edge Neighbors M"
          command="SetMappingLineDistanceNbrNeighbors"
          default_values="10"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          K-nearest neighbors point to consider to compute the Variance-Covariance
          matrix of the neighborhood to define the Mahalanobis distance function.
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="# Plane Neighbors M"
          command="SetMappingPlaneDistanceNbrNeighbors"
          default_values="5"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          K-nearest neighbors points to consider to compute the Variance-Covariance
          matrix of the neighborhood to define the Mahalanobis distance function.
        </Documentation>
      </IntVectorProperty>

      <DoubleVectorProperty
          name="Linearity Factor #1 M"
          command="SetMappingLineDistancefactor"
          default_values="5"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject an edge keypoint if its neighborhood is not distributed
          along a line eigenvalue1 > Factor * eigenvalue2
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Planarity Factor #1 M"
          command="SetMappingPlaneDistancefactor1"
          default_values="35"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject a planar keypoint if its neighborhood is not distributed
          along a plane: Factor1 * eigenvalue2 > eigenvalue1 and
          eigenvalue2 > Factor2 * eigenvalue3
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Planarity Factor #2 M"
          command="SetMappingPlaneDistancefactor2"
          default_values="8"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject a planar keypoint if its neighborhood is not distributed
          along a plane: Factor1 * eigenvalue2 > eigenvalue1 and
          eigenvalue2 > Factor2 * eigenvalue3
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Maximum Inlier Distance Ransac Line Fitting"
          command="SetMappingLineMaxDistInlier"
          default_values="0.2"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject an edge point if its neighborhood has points that
          are too far from the fitted line (degenerated ellipsoid)
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Max Edge-Neighbors Distance To Fitted Line M"
          command="SetMappingMaxLineDistance"
          default_values="0.2"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject an edge point if its neighborhood has points that
          are too far from the fitted line (degenerated ellipsoid)
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Max Plane-Neighbors Distance To Fitted Plane M"
          command="SetMappingMaxPlaneDistance"
          default_values="0.2"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Reject a planar point if its neighborhood has points that
          are too far from the fitted plane (degenerated ellipsoid)
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Mapping Init Loss Scale"
          command="SetMappingInitLossScale"
          default_values="0.7"
          number_of_elements="1"
          panel_visibility="advanced">
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Mapping Final Loss Scale"
          command="SetMappingFinalLossScale"
          default_values="0.05"
          number_of_elements="1"
          panel_visibility="advanced">
      </DoubleVectorProperty>

     <PropertyGroup label="Mapping ICP Matching And Optimization Parameters">
       <Property name="Lev-Mardt Maximum Iteration M" />
       <Property name="ICP Maximum Itertation M" />
       <Property name="# Edges Neighbors Minimum After Ransac M" />
       <Property name="# Edge Neighbors M" />
       <Property name="# Plane Neighbors M" />
       <Property name="Linearity Factor #1 M" />
       <Property name="Planarity Factor #1 M" />
       <Property name="Planarity Factor #2 M" />
       <Property name="Maximum Inlier Distance Ransac Line Fitting" />
       <Property name="Max Edge-Neighbors Distance To Fitted Line M" />
       <Property name="Max Plane-Neighbors Distance To Fitted Plane M" />
       <Property name="Mapping Init Loss Scale" />
       <Property name="Mapping Final Loss Scale" />
     </PropertyGroup>

     <!-- ==================== Map Parameters ==================== -->
     <DoubleVectorProperty
         name="Map Edges Voxel Grid Leaf Size"
         command="SetVoxelGridLeafSizeEdges"
         default_values="0.45"
         number_of_elements="1"
         panel_visibility="advanced">
       <Documentation>
          Size of the leaf when downsampling the environment map using
          a voxel grid filter. It should not be too big or some high
          frequency geometric information will be lost. It should not
          be too low or the geometric information will be too local
        </Documentation>
     </DoubleVectorProperty>

     <DoubleVectorProperty
         name="Map Planes Voxel Grid Leaf Size"
         command="SetVoxelGridLeafSizePlanes"
         default_values="0.6"
         number_of_elements="1"
         panel_visibility="advanced">
       <Documentation>
          Size of the leaf when downsampling the environment map using
          a voxel grid filter. It should not be too big or some high
          frequency geometric information will be lost. It should not
          be too low or the geometric information will be too local
        </Documentation>
     </DoubleVectorProperty>

     <DoubleVectorProperty
         name="Map Blobs Voxel Grid Leaf Size"
         command="SetVoxelGridLeafSizeBlobs"
         default_values="0.12"
         number_of_elements="1"
         panel_visibility="advanced">
       <Documentation>
          Size of the leaf when downsampling the environment map using
          a voxel grid filter. It should not be too big or some high
          frequency geometric information will be lost. It should not
          be too low or the geometric information will be too local
        </Documentation>
     </DoubleVectorProperty>

     <IntVectorProperty
         name="Map Voxel Grid Size"
         command="SetVoxelGridSize"
         default_values="50"
         number_of_elements="1"
         panel_visibility="advanced">
       <Documentation>
          Size of the map used to store the keypoints. The map needs to
          have a size sufficient to store at least one frame.
        </Documentation>
     </IntVectorProperty>

     <DoubleVectorProperty
         name="Map Voxel Grid Resolution"
         command="SetVoxelGridResolution"
         default_values="10"
         number_of_elements="1"
         panel_visibility="advanced">
       <Documentation>
          Resolution of the map. It should not be too big or too much
          points will be considered when trying to position the frame in
          the position.This do not impact accuracy but only speed.
        </Documentation>
     </DoubleVectorProperty>

     <PropertyGroup label="Map Parameters">
        <Property name="Map Edges Voxel Grid Leaf Size" />
        <Property name="Map Planes Voxel Grid Leaf Size" />
        <Property name="Map Blobs Voxel Grid Leaf Size" />
        <Property name="Map Voxel Grid Size" />
        <Property name="Map Voxel Grid Resolution" />
     </PropertyGroup>

    </SourceProxy>
  </ProxyGroup>
  <!-- End Online Slam -->

  <!-- Begin Offline Slam -->
  <ProxyGroup name="filters">
    <SourceProxy
      name="Slam (Offline)"
      class="vtkSlamManager"
      label="Slam (Offline)"
      base_proxygroup="filters"
      base_proxyname="Slam (Online)">
      <Documentation
        short_help="Performs SLAM algorithm on the Lidar sensor's point cloud"
        long_help="Performs SLAM algorithm on the Lidar sensor's point cloud.
                   The SLAM algorithm is composed of three sequential steps:
                   - Sampling strategy: extract keypoints that provide strong geometric information
                   - Ego Motion: Sensor motion estimation between two frames
                   - Mapping: Map the frame in a environment map">
        filter which performs slam on points data.
      </Documentation>

      <IntVectorProperty
          name="All Frame"
          command="SetAllFrame"
          default_values="1"
          number_of_elements="1">
          <BooleanDomain name="bool" />
        <Documentation>
          Process all frame
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="First Frame"
          command="SetFirstFrame"
          default_values="0"
          number_of_elements="1">
          <Hints>
            <PropertyWidgetDecorator type="EnableWidgetDecorator">
              <Property name="All Frame" function="boolean_invert" />
            </PropertyWidgetDecorator>
          </Hints>
        <Documentation>
          Set the first frame to process
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="Last Frame"
          command="SetLastFrame"
          default_values="0"
          number_of_elements="1">
          <Hints>
            <PropertyWidgetDecorator type="EnableWidgetDecorator">
              <Property name="All Frame" function="boolean_invert" />
            </PropertyWidgetDecorator>
          </Hints>
        <Documentation>
          Set the last frame to process
        </Documentation>
      </IntVectorProperty>

      <IntVectorProperty
          name="StepSize"
          command="SetStepSize"
          default_values="1"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Process one frame every StepSize frames (exemple: every (1) frames, every 2 frames, every 3 frames, and so on). A StepSize of 1 (the default value) means that all frames between the first and the last (included) will be used. This property can be useful to trade robustness (StepSize equal to 1) and accuracy for speed (StepSize bigger than 1).
        </Documentation>
      </IntVectorProperty>

    </SourceProxy>
  </ProxyGroup>
  <!-- End Online Slam -->



  <!-- Begin KeyPointsExtractor -->
  <ProxyGroup name="KeyPointsExtractor">
    <Proxy
      name="SpinningSensorKeypointExtractor"
      class="vtkSpinningSensorKeypointExtractor"
      label="SpinningSensorKeypointExtractor">

      <IntVectorProperty
          name="Neighbor Width"
          command="SetNeighborWidth"
          default_values="4"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Number of neighbors used to estimate the scan lines
          scores (curvature, angles, depth gap, ...)
        </Documentation>
      </IntVectorProperty>

      <DoubleVectorProperty
          name="Minimum Distance To Sensor"
          command="SetMinDistanceToSensor"
          default_values="3"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Minimal distance between a point and the sensor to be
          processed for the keypoint extraction. In other words,
          all points too close from the sensor are automatically
          rejected. In meters
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Minimum Sinus To Be Considered As Edge"
          command="SetEdgeSinAngleThreshold"
          default_values="0.86"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          One strategy to consider a point as an edge keypoint is to compute
          the angle between the two lines that fit its previous and next neighborhood.
          If the angle is close enought to 90° (sin(Angle) high enought) we consider
          the point as an edge keypoint.
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Maximum Sinus To Be Considered As Planar"
          command="SetPlaneSinAngleThreshold"
          default_values="0.5"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          One strategy to consider a point as a planar keypoint is to compute
          the angle between the two lines that fit its previous and next neighborhood.
          If the angle is close enought to 0° or 180° (sin(Angle) low enought) we consider
          the point as a planar keypoint.
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Minimum Depth Gapt To Be Considered As Edge"
          command="SetEdgeDepthGapThreshold"
          default_values="0.15"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          One strategy to consider a point as an edge keypoint is to compute
          the gap between the point and its neighborhood. Its left and right
          neighborhood are fitted with a line and we then compute the gap as
          being the distance between the point and the fitted lines. If the gap
          is high enought, we consider the point as an edge keypoint
        </Documentation>
      </DoubleVectorProperty>

      <DoubleVectorProperty
          name="Angle Resolution Between Two Firing"
          command="SetAngleResolution"
          default_values="0.00698"
          number_of_elements="1"
          panel_visibility="advanced">
        <Documentation>
          Azimutal angle resolution of the Lidar sensor. This angle
          resolution is used to compute an expected distance between two
          consecutives firing. From this expected distance, we can detect
          if a point is a potential gap and launch more investigation
        </Documentation>
      </DoubleVectorProperty>

      <PropertyGroup label="Keypoint Extraction Parameters">
        <Property name="Neighbor Width" />
        <Property name="Minimum Distance To Sensor" />
        <Property name="Minimum Sinus To Be Considered As Edge" />
        <Property name="Maximum Sinus To Be Considered As Planar" />
        <Property name="Minimum Depth Gapt To Be Considered As Edge" />
        <Property name="Angle Resolution Between Two Firing" />
      </PropertyGroup>
    </Proxy>
  </ProxyGroup>
  <!-- End KeyPointsExtractor -->

</ServerManagerConfiguration>
