Initial commit
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of Ceres Solver options.
|
||||
/// Configure the Ceres solver. See the Ceres documentation for more
|
||||
/// information: https://code.google.com/p/ceres-solver/
|
||||
/// </summary>
|
||||
public struct CeresSolverOptions(
|
||||
bool useNonmonotonicSteps,
|
||||
int maxNumIterations,
|
||||
int numThreads,
|
||||
double? functionTolerance = null,
|
||||
double? gradientTolerance = null,
|
||||
double? parameterTolerance = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// Use non-monotonic steps in the solver.
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_nonmonotonic_steps")]
|
||||
public bool UseNonmonotonicSteps { get; set; } = useNonmonotonicSteps;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of iterations for the solver.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_num_iterations")]
|
||||
public int MaxNumIterations { get; set; } = maxNumIterations;
|
||||
|
||||
/// <summary>
|
||||
/// Number of threads to use in the solver.
|
||||
/// </summary>
|
||||
[JsonPropertyName("num_threads")]
|
||||
public int NumThreads { get; set; } = numThreads;
|
||||
|
||||
/// <summary>
|
||||
/// Function tolerance for convergence check.
|
||||
/// Minimizer terminates when (new_cost - old_cost) < function_tolerance * old_cost
|
||||
/// </summary>
|
||||
[JsonPropertyName("function_tolerance")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? FunctionTolerance { get; set; } = functionTolerance;
|
||||
|
||||
/// <summary>
|
||||
/// Gradient tolerance for convergence check.
|
||||
/// Minimizer terminates when max_i |x - Project(Plus(x, -g(x))| < gradient_tolerance
|
||||
/// </summary>
|
||||
[JsonPropertyName("gradient_tolerance")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? GradientTolerance { get; set; } = gradientTolerance;
|
||||
|
||||
/// <summary>
|
||||
/// Parameter tolerance for convergence check.
|
||||
/// Minimizer terminates when |step|_2 <= parameter_tolerance * (|x|_2 + parameter_tolerance)
|
||||
/// </summary>
|
||||
[JsonPropertyName("parameter_tolerance")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? ParameterTolerance { get; set; } = parameterTolerance;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using CartographerSharp.Models.Transform;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.GroundTruth;
|
||||
|
||||
/// <summary>
|
||||
/// Relation between two timestamps with expected relative transform.
|
||||
/// </summary>
|
||||
public struct Relation
|
||||
{
|
||||
[JsonPropertyName("timestamp1")]
|
||||
public long Timestamp1 { get; set; }
|
||||
|
||||
[JsonPropertyName("timestamp2")]
|
||||
public long Timestamp2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The 'expected' relative transform of the tracking frame from 'timestamp2'
|
||||
/// to 'timestamp1'.
|
||||
/// </summary>
|
||||
[JsonPropertyName("expected")]
|
||||
public Rigid3dProto Expected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Covered distance between the two timestamps.
|
||||
/// </summary>
|
||||
[JsonPropertyName("covered_distance")]
|
||||
public double CoveredDistance { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ground truth data containing relations.
|
||||
/// </summary>
|
||||
public struct GroundTruth
|
||||
{
|
||||
[JsonPropertyName("relation")]
|
||||
public List<Relation> Relations { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of 2D cell limits.
|
||||
/// </summary>
|
||||
public struct CellLimits
|
||||
{
|
||||
[JsonPropertyName("num_x_cells")]
|
||||
public int NumXCells { get; set; }
|
||||
|
||||
[JsonPropertyName("num_y_cells")]
|
||||
public int NumYCells { get; set; }
|
||||
|
||||
public CellLimits(int numXCells, int numYCells)
|
||||
{
|
||||
NumXCells = numXCells;
|
||||
NumYCells = numYCells;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of Ceres scan matcher options for 2D.
|
||||
/// </summary>
|
||||
public struct CeresScanMatcherOptions2D
|
||||
{
|
||||
/// <summary>
|
||||
/// Scaling parameters for each cost functor.
|
||||
/// </summary>
|
||||
[JsonPropertyName("occupied_space_weight")]
|
||||
public double OccupiedSpaceWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("translation_weight")]
|
||||
public double TranslationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("rotation_weight")]
|
||||
public double RotationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// High resolution occupied space weight.
|
||||
/// Used when matching against high resolution grid.
|
||||
/// </summary>
|
||||
[JsonPropertyName("high_res_occupied_space_weight")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? HighResOccupiedSpaceWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// High resolution translation weight.
|
||||
/// Used when matching against high resolution grid.
|
||||
/// </summary>
|
||||
[JsonPropertyName("high_res_translation_weight")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? HighResTranslationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// High resolution rotation weight.
|
||||
/// Used when matching against high resolution grid.
|
||||
/// </summary>
|
||||
[JsonPropertyName("high_res_rotation_weight")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? HighResRotationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Landmark weight.
|
||||
/// Weight for landmark constraints in scan matching.
|
||||
/// </summary>
|
||||
[JsonPropertyName("landmark_weight")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? LandmarkWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ceres solver options.
|
||||
/// </summary>
|
||||
[JsonPropertyName("ceres_solver_options")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Models.Common.CeresSolverOptions? CeresSolverOptions { get; set; }
|
||||
|
||||
public CeresScanMatcherOptions2D(
|
||||
double occupiedSpaceWeight,
|
||||
double translationWeight,
|
||||
double rotationWeight,
|
||||
Models.Common.CeresSolverOptions? ceresSolverOptions = null,
|
||||
double? highResOccupiedSpaceWeight = null,
|
||||
double? highResTranslationWeight = null,
|
||||
double? highResRotationWeight = null,
|
||||
double? landmarkWeight = null)
|
||||
{
|
||||
OccupiedSpaceWeight = occupiedSpaceWeight;
|
||||
TranslationWeight = translationWeight;
|
||||
RotationWeight = rotationWeight;
|
||||
CeresSolverOptions = ceresSolverOptions;
|
||||
HighResOccupiedSpaceWeight = highResOccupiedSpaceWeight;
|
||||
HighResTranslationWeight = highResTranslationWeight;
|
||||
HighResRotationWeight = highResRotationWeight;
|
||||
LandmarkWeight = landmarkWeight;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Common;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Intensity cost function options for 3D scan matching.
|
||||
/// </summary>
|
||||
public struct IntensityCostFunctionOptions3D
|
||||
{
|
||||
[JsonPropertyName("weight")]
|
||||
public double Weight { get; set; }
|
||||
|
||||
[JsonPropertyName("huber_scale")]
|
||||
public double HuberScale { get; set; }
|
||||
|
||||
[JsonPropertyName("intensity_threshold")]
|
||||
public double IntensityThreshold { get; set; }
|
||||
|
||||
public IntensityCostFunctionOptions3D(double weight, double huberScale, double intensityThreshold)
|
||||
{
|
||||
Weight = weight;
|
||||
HuberScale = huberScale;
|
||||
IntensityThreshold = intensityThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of Ceres scan matcher options for 3D.
|
||||
/// </summary>
|
||||
public struct CeresScanMatcherOptions3D
|
||||
{
|
||||
/// <summary>
|
||||
/// Occupied space weights for each point cloud/grid pair.
|
||||
/// </summary>
|
||||
[JsonPropertyName("occupied_space_weight")]
|
||||
public List<double> OccupiedSpaceWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Intensity cost function options for each point cloud/grid pair.
|
||||
/// </summary>
|
||||
[JsonPropertyName("intensity_cost_function_options")]
|
||||
public List<IntensityCostFunctionOptions3D> IntensityCostFunctionOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Translation weight.
|
||||
/// </summary>
|
||||
[JsonPropertyName("translation_weight")]
|
||||
public double TranslationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Rotation weight.
|
||||
/// </summary>
|
||||
[JsonPropertyName("rotation_weight")]
|
||||
public double RotationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Only optimize yaw (ignore roll and pitch).
|
||||
/// </summary>
|
||||
[JsonPropertyName("only_optimize_yaw")]
|
||||
public bool OnlyOptimizeYaw { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ceres solver options.
|
||||
/// </summary>
|
||||
[JsonPropertyName("ceres_solver_options")]
|
||||
public CeresSolverOptions? CeresSolverOptions { get; set; }
|
||||
|
||||
public CeresScanMatcherOptions3D(
|
||||
List<double>? occupiedSpaceWeight = null,
|
||||
List<IntensityCostFunctionOptions3D>? intensityCostFunctionOptions = null,
|
||||
double translationWeight = 5.0,
|
||||
double rotationWeight = 200.0,
|
||||
bool onlyOptimizeYaw = false,
|
||||
CeresSolverOptions? ceresSolverOptions = null)
|
||||
{
|
||||
OccupiedSpaceWeight = occupiedSpaceWeight ?? new List<double> { 5.0 };
|
||||
IntensityCostFunctionOptions = intensityCostFunctionOptions ?? new List<IntensityCostFunctionOptions3D>();
|
||||
TranslationWeight = translationWeight;
|
||||
RotationWeight = rotationWeight;
|
||||
OnlyOptimizeYaw = onlyOptimizeYaw;
|
||||
CeresSolverOptions = ceresSolverOptions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of constraint builder options.
|
||||
/// </summary>
|
||||
public struct ConstraintBuilderOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// A constraint will be added if the proportion of added constraints to
|
||||
/// potential constraints drops below this number.
|
||||
/// </summary>
|
||||
[JsonPropertyName("sampling_ratio")]
|
||||
public double SamplingRatio { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Threshold for poses to be considered near a submap.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_constraint_distance")]
|
||||
public double MaxConstraintDistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Threshold for the scan match score below which a match is not considered.
|
||||
/// Low scores indicate that the scan and map do not look similar.
|
||||
/// </summary>
|
||||
[JsonPropertyName("min_score")]
|
||||
public double MinScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Threshold below which global localizations are not trusted.
|
||||
/// </summary>
|
||||
[JsonPropertyName("global_localization_min_score")]
|
||||
public double GlobalLocalizationMinScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Weight used in the optimization problem for the translational component of
|
||||
/// loop closure constraints.
|
||||
/// </summary>
|
||||
[JsonPropertyName("loop_closure_translation_weight")]
|
||||
public double LoopClosureTranslationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Weight used in the optimization problem for the rotational component of
|
||||
/// loop closure constraints.
|
||||
/// </summary>
|
||||
[JsonPropertyName("loop_closure_rotation_weight")]
|
||||
public double LoopClosureRotationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, logs information of loop-closing constraints for debugging.
|
||||
/// </summary>
|
||||
[JsonPropertyName("log_matches")]
|
||||
public bool LogMatches { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Options for the fast correlative scan matcher (2D).
|
||||
/// </summary>
|
||||
[JsonPropertyName("fast_correlative_scan_matcher_options")]
|
||||
public FastCorrelativeScanMatcherOptions2D? FastCorrelativeScanMatcherOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Options for the Ceres scan matcher (2D).
|
||||
/// </summary>
|
||||
[JsonPropertyName("ceres_scan_matcher_options")]
|
||||
public CeresScanMatcherOptions2D? CeresScanMatcherOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Options for the fast correlative scan matcher (3D).
|
||||
/// </summary>
|
||||
[JsonPropertyName("fast_correlative_scan_matcher_options_3d")]
|
||||
public FastCorrelativeScanMatcherOptions3D? FastCorrelativeScanMatcherOptions3D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Options for the Ceres scan matcher (3D).
|
||||
/// </summary>
|
||||
[JsonPropertyName("ceres_scan_matcher_options_3d")]
|
||||
public CeresScanMatcherOptions3D? CeresScanMatcherOptions3D { get; set; }
|
||||
|
||||
public ConstraintBuilderOptions()
|
||||
{
|
||||
SamplingRatio = 0.3;
|
||||
MaxConstraintDistance = 15.0;
|
||||
MinScore = 0.55;
|
||||
GlobalLocalizationMinScore = 0.6;
|
||||
LoopClosureTranslationWeight = 1.1e4;
|
||||
LoopClosureRotationWeight = 1.0;
|
||||
LogMatches = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of fast correlative scan matcher options for 2D.
|
||||
/// </summary>
|
||||
public struct FastCorrelativeScanMatcherOptions2D
|
||||
{
|
||||
/// <summary>
|
||||
/// Linear search window in meters.
|
||||
/// </summary>
|
||||
[JsonPropertyName("linear_search_window")]
|
||||
public double LinearSearchWindow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Angular search window in radians.
|
||||
/// </summary>
|
||||
[JsonPropertyName("angular_search_window")]
|
||||
public double AngularSearchWindow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Branch and bound depth.
|
||||
/// </summary>
|
||||
[JsonPropertyName("branch_and_bound_depth")]
|
||||
public int BranchAndBoundDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Linear search window for localization (meters).
|
||||
/// Used when performing global localization.
|
||||
/// </summary>
|
||||
[JsonPropertyName("localization_linear_search_window")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? LocalizationLinearSearchWindow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Angular search window for localization (radians).
|
||||
/// Used when performing global localization.
|
||||
/// </summary>
|
||||
[JsonPropertyName("localization_angular_search_window")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? LocalizationAngularSearchWindow { get; set; }
|
||||
|
||||
public FastCorrelativeScanMatcherOptions2D(
|
||||
double linearSearchWindow = 0.1,
|
||||
double angularSearchWindow = 0.1,
|
||||
int branchAndBoundDepth = 7,
|
||||
double? localizationLinearSearchWindow = null,
|
||||
double? localizationAngularSearchWindow = null)
|
||||
{
|
||||
LinearSearchWindow = linearSearchWindow;
|
||||
AngularSearchWindow = angularSearchWindow;
|
||||
BranchAndBoundDepth = branchAndBoundDepth;
|
||||
LocalizationLinearSearchWindow = localizationLinearSearchWindow;
|
||||
LocalizationAngularSearchWindow = localizationAngularSearchWindow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of fast correlative scan matcher options for 3D.
|
||||
/// </summary>
|
||||
public struct FastCorrelativeScanMatcherOptions3D
|
||||
{
|
||||
/// <summary>
|
||||
/// Branch and bound depth.
|
||||
/// </summary>
|
||||
[JsonPropertyName("branch_and_bound_depth")]
|
||||
public int BranchAndBoundDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Full resolution depth.
|
||||
/// </summary>
|
||||
[JsonPropertyName("full_resolution_depth")]
|
||||
public int FullResolutionDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum rotational score.
|
||||
/// </summary>
|
||||
[JsonPropertyName("min_rotational_score")]
|
||||
public double MinRotationalScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum low resolution score.
|
||||
/// </summary>
|
||||
[JsonPropertyName("min_low_resolution_score")]
|
||||
public double MinLowResolutionScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Linear XY search window (meters).
|
||||
/// </summary>
|
||||
[JsonPropertyName("linear_xy_search_window")]
|
||||
public double LinearXySearchWindow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Linear Z search window (meters).
|
||||
/// </summary>
|
||||
[JsonPropertyName("linear_z_search_window")]
|
||||
public double LinearZSearchWindow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Angular search window (radians).
|
||||
/// </summary>
|
||||
[JsonPropertyName("angular_search_window")]
|
||||
public double AngularSearchWindow { get; set; }
|
||||
|
||||
public FastCorrelativeScanMatcherOptions3D(
|
||||
int branchAndBoundDepth = 7,
|
||||
int fullResolutionDepth = 2,
|
||||
double minRotationalScore = 0.77,
|
||||
double minLowResolutionScore = 0.55,
|
||||
double linearXySearchWindow = 0.1,
|
||||
double linearZSearchWindow = 0.1,
|
||||
double angularSearchWindow = 0.1)
|
||||
{
|
||||
BranchAndBoundDepth = branchAndBoundDepth;
|
||||
FullResolutionDepth = fullResolutionDepth;
|
||||
MinRotationalScore = minRotationalScore;
|
||||
MinLowResolutionScore = minLowResolutionScore;
|
||||
LinearXySearchWindow = linearXySearchWindow;
|
||||
LinearZSearchWindow = linearZSearchWindow;
|
||||
AngularSearchWindow = angularSearchWindow;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a 2D grid.
|
||||
/// </summary>
|
||||
public struct Grid2D
|
||||
{
|
||||
/// <summary>
|
||||
/// Cell box for known cells.
|
||||
/// </summary>
|
||||
public struct CellBox
|
||||
{
|
||||
[JsonPropertyName("max_x")]
|
||||
public int MaxX { get; set; }
|
||||
|
||||
[JsonPropertyName("max_y")]
|
||||
public int MaxY { get; set; }
|
||||
|
||||
[JsonPropertyName("min_x")]
|
||||
public int MinX { get; set; }
|
||||
|
||||
[JsonPropertyName("min_y")]
|
||||
public int MinY { get; set; }
|
||||
|
||||
public CellBox(int maxX, int maxY, int minX, int minY)
|
||||
{
|
||||
MaxX = maxX;
|
||||
MaxY = maxY;
|
||||
MinX = minX;
|
||||
MinY = minY;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("limits")]
|
||||
public MapLimits Limits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// These values are actually int16s, but protos don't have a native int16 type.
|
||||
/// </summary>
|
||||
[JsonPropertyName("cells")]
|
||||
public List<int> Cells { get; set; }
|
||||
|
||||
[JsonPropertyName("known_cells_box")]
|
||||
public CellBox KnownCellsBox { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Grid type - oneof probability_grid_2d or tsdf_2d.
|
||||
/// Using JsonPolymorphic for oneof support in System.Text.Json.
|
||||
/// </summary>
|
||||
[JsonPropertyName("probability_grid_2d")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public ProbabilityGrid? ProbabilityGrid2D { get; set; }
|
||||
|
||||
[JsonPropertyName("tsdf_2d")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public TSDF2D? Tsdf2D { get; set; }
|
||||
|
||||
[JsonPropertyName("min_correspondence_cost")]
|
||||
public double MinCorrespondenceCost { get; set; }
|
||||
|
||||
[JsonPropertyName("max_correspondence_cost")]
|
||||
public double MaxCorrespondenceCost { get; set; }
|
||||
|
||||
public Grid2D(
|
||||
MapLimits limits,
|
||||
List<int>? cells = null,
|
||||
CellBox knownCellsBox = default,
|
||||
ProbabilityGrid? probabilityGrid2D = null,
|
||||
TSDF2D? tsdf2D = null,
|
||||
double minCorrespondenceCost = 0.0,
|
||||
double maxCorrespondenceCost = 0.0)
|
||||
{
|
||||
Limits = limits;
|
||||
Cells = cells ?? new List<int>();
|
||||
KnownCellsBox = knownCellsBox;
|
||||
ProbabilityGrid2D = probabilityGrid2D;
|
||||
Tsdf2D = tsdf2D;
|
||||
MinCorrespondenceCost = minCorrespondenceCost;
|
||||
MaxCorrespondenceCost = maxCorrespondenceCost;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of grid options for 2D.
|
||||
/// </summary>
|
||||
public struct GridOptions2D
|
||||
{
|
||||
public enum GridType
|
||||
{
|
||||
InvalidGrid = 0,
|
||||
ProbabilityGrid = 1,
|
||||
Tsdf = 2
|
||||
}
|
||||
|
||||
[JsonPropertyName("grid_type")]
|
||||
public GridType GridTypeValue { get; set; }
|
||||
|
||||
[JsonPropertyName("resolution")]
|
||||
public double Resolution { get; set; }
|
||||
|
||||
[JsonPropertyName("tsdf_options")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public TSDFOptions2D? TsdfOptions { get; set; }
|
||||
|
||||
public GridOptions2D(GridType gridType, double resolution, TSDFOptions2D? tsdfOptions = null)
|
||||
{
|
||||
GridTypeValue = gridType;
|
||||
Resolution = resolution;
|
||||
TsdfOptions = tsdfOptions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Options for TSDF2D grid.
|
||||
/// </summary>
|
||||
public struct TSDFOptions2D
|
||||
{
|
||||
[JsonPropertyName("truncation_distance")]
|
||||
public double TruncationDistance { get; set; }
|
||||
|
||||
[JsonPropertyName("max_weight")]
|
||||
public double MaxWeight { get; set; }
|
||||
|
||||
public TSDFOptions2D(double truncationDistance, double maxWeight)
|
||||
{
|
||||
TruncationDistance = truncationDistance;
|
||||
MaxWeight = maxWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a hybrid grid.
|
||||
/// </summary>
|
||||
public struct HybridGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolution of the grid.
|
||||
/// </summary>
|
||||
[JsonPropertyName("resolution")]
|
||||
public double Resolution { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X indices. '{x, y, z}_indices[i]' is the index of 'values[i]'.
|
||||
/// </summary>
|
||||
[JsonPropertyName("x_indices")]
|
||||
public List<int> XIndices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Y indices.
|
||||
/// </summary>
|
||||
[JsonPropertyName("y_indices")]
|
||||
public List<int> YIndices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Z indices.
|
||||
/// </summary>
|
||||
[JsonPropertyName("z_indices")]
|
||||
public List<int> ZIndices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The entries in 'values' should be uint16s, not int32s, but protos don't
|
||||
/// have a uint16 type.
|
||||
/// </summary>
|
||||
[JsonPropertyName("values")]
|
||||
public List<int> Values { get; set; }
|
||||
|
||||
public HybridGrid(
|
||||
double resolution,
|
||||
List<int>? xIndices = null,
|
||||
List<int>? yIndices = null,
|
||||
List<int>? zIndices = null,
|
||||
List<int>? values = null)
|
||||
{
|
||||
Resolution = resolution;
|
||||
XIndices = xIndices ?? new List<int>();
|
||||
YIndices = yIndices ?? new List<int>();
|
||||
ZIndices = zIndices ?? new List<int>();
|
||||
Values = values ?? new List<int>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using CeresSolverOptions = CartographerSharp.Models.Common.CeresSolverOptions;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of IMU-based pose extrapolator options.
|
||||
/// </summary>
|
||||
public struct ImuBasedPoseExtrapolatorOptions
|
||||
{
|
||||
[JsonPropertyName("pose_queue_duration")]
|
||||
public double PoseQueueDuration { get; set; }
|
||||
|
||||
[JsonPropertyName("gravity_constant")]
|
||||
public double GravityConstant { get; set; }
|
||||
|
||||
[JsonPropertyName("pose_translation_weight")]
|
||||
public double PoseTranslationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("pose_rotation_weight")]
|
||||
public double PoseRotationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("imu_acceleration_weight")]
|
||||
public double ImuAccelerationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("imu_rotation_weight")]
|
||||
public double ImuRotationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("solver_options")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public CeresSolverOptions? SolverOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("odometry_translation_weight")]
|
||||
public double OdometryTranslationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("odometry_rotation_weight")]
|
||||
public double OdometryRotationWeight { get; set; }
|
||||
|
||||
public ImuBasedPoseExtrapolatorOptions(
|
||||
double poseQueueDuration = 0.001,
|
||||
double gravityConstant = 9.806,
|
||||
double poseTranslationWeight = 1.0,
|
||||
double poseRotationWeight = 1.0,
|
||||
double imuAccelerationWeight = 1.0,
|
||||
double imuRotationWeight = 1.0,
|
||||
CeresSolverOptions? solverOptions = null,
|
||||
double odometryTranslationWeight = 1.0,
|
||||
double odometryRotationWeight = 1.0)
|
||||
{
|
||||
PoseQueueDuration = poseQueueDuration;
|
||||
GravityConstant = gravityConstant;
|
||||
PoseTranslationWeight = poseTranslationWeight;
|
||||
PoseRotationWeight = poseRotationWeight;
|
||||
ImuAccelerationWeight = imuAccelerationWeight;
|
||||
ImuRotationWeight = imuRotationWeight;
|
||||
SolverOptions = solverOptions;
|
||||
OdometryTranslationWeight = odometryTranslationWeight;
|
||||
OdometryRotationWeight = odometryRotationWeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using AdaptiveVoxelFilterOptions = CartographerSharp.Models.Sensor.AdaptiveVoxelFilterOptions;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of local trajectory builder options for 2D.
|
||||
/// </summary>
|
||||
public struct LocalTrajectoryBuilderOptions2D
|
||||
{
|
||||
/// <summary>
|
||||
/// Rangefinder points outside these ranges will be dropped.
|
||||
/// </summary>
|
||||
[JsonPropertyName("min_range")]
|
||||
public double MinRange { get; set; }
|
||||
|
||||
[JsonPropertyName("max_range")]
|
||||
public double MaxRange { get; set; }
|
||||
|
||||
[JsonPropertyName("min_z")]
|
||||
public double MinZ { get; set; }
|
||||
|
||||
[JsonPropertyName("max_z")]
|
||||
public double MaxZ { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Points beyond 'max_range' will be inserted with this length as empty space.
|
||||
/// </summary>
|
||||
[JsonPropertyName("missing_data_ray_length")]
|
||||
public double MissingDataRayLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of range data to accumulate into one unwarped, combined range data
|
||||
/// to use for scan matching.
|
||||
/// </summary>
|
||||
[JsonPropertyName("num_accumulated_range_data")]
|
||||
public int NumAccumulatedRangeData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Voxel filter that gets applied to the range data immediately after cropping.
|
||||
/// </summary>
|
||||
[JsonPropertyName("voxel_filter_size")]
|
||||
public double VoxelFilterSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to solve the online scan matching first using the correlative scan
|
||||
/// matcher to generate a good starting point for Ceres.
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_online_correlative_scan_matching")]
|
||||
public bool UseOnlineCorrelativeScanMatching { get; set; }
|
||||
|
||||
[JsonPropertyName("real_time_correlative_scan_matcher_options")]
|
||||
public RealTimeCorrelativeScanMatcherOptions RealTimeCorrelativeScanMatcherOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("ceres_scan_matcher_options")]
|
||||
public CeresScanMatcherOptions2D CeresScanMatcherOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("motion_filter_options")]
|
||||
public MotionFilterOptions MotionFilterOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("submaps_options")]
|
||||
public SubmapsOptions2D SubmapsOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if IMU data should be expected and used.
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_imu_data")]
|
||||
public bool UseImuData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adaptive voxel filter options for 2D.
|
||||
/// Used instead of fixed voxel_filter_size when configured.
|
||||
/// </summary>
|
||||
[JsonPropertyName("adaptive_voxel_filter_options")]
|
||||
public Models.Sensor.AdaptiveVoxelFilterOptions AdaptiveVoxelFilterOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Voxel filter used to compute a sparser point cloud for finding loop closures.
|
||||
/// </summary>
|
||||
[JsonPropertyName("loop_closure_adaptive_voxel_filter_options")]
|
||||
public Models.Sensor.AdaptiveVoxelFilterOptions LoopClosureAdaptiveVoxelFilterOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Time constant in seconds for the orientation moving average based on
|
||||
/// observed gravity via the IMU. It should be chosen so that the error
|
||||
/// 1. from acceleration measurements not due to gravity (which gets worse when
|
||||
/// the constant is reduced) and
|
||||
/// 2. from integration of angular velocities (which gets worse when the
|
||||
/// constant is increased) is balanced.
|
||||
/// TODO(schwoere,wohe): Remove this constant. This is only used for ROS and
|
||||
/// was replaced by pose_extrapolator_options.
|
||||
/// </summary>
|
||||
[JsonPropertyName("imu_gravity_time_constant")]
|
||||
public double ImuGravityTimeConstant { get; set; }
|
||||
|
||||
[JsonPropertyName("pose_extrapolator_options")]
|
||||
public PoseExtrapolatorOptions PoseExtrapolatorOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Scan matcher options used when applying a pending initial pose (SetInitialPose called mid-run).
|
||||
/// The next accumulated range data uses this pose as prediction and matches with wider search and stricter Ceres.
|
||||
/// Configured with wider search windows for relocalization scenarios.
|
||||
/// </summary>
|
||||
[JsonPropertyName("initial_pose_real_time_correlative_scan_matcher_options")]
|
||||
public RealTimeCorrelativeScanMatcherOptions InitialPoseRealTimeCorrelativeScanMatcherOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("initial_pose_ceres_scan_matcher_options")]
|
||||
public CeresScanMatcherOptions2D InitialPoseCeresScanMatcherOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, provides a confidence score for the pose estimate based on
|
||||
/// real-time correlative scan matching.
|
||||
/// Match C++: provide_confidence_score option in LocalTrajectoryBuilderOptions2D
|
||||
/// </summary>
|
||||
[JsonPropertyName("provide_confidence_score")]
|
||||
public bool ProvideConfidenceScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Soft limit for Ceres scan match cost. When ceresScore exceeds this threshold
|
||||
/// but is below HardLimit, the pose is trusted (AddPose is called) but the scan
|
||||
/// is NOT inserted into the submap to avoid corrupting the map.
|
||||
/// Set to 0 to disable. Default: 0 (disabled).
|
||||
/// DEPRECATED: Use ProbabilityGridCeresScoreSoftLimit / TsdfCeresScoreSoftLimit instead.
|
||||
/// Kept as fallback when per-grid-type values are not set (both == 0).
|
||||
/// </summary>
|
||||
[JsonPropertyName("ceres_score_soft_limit")]
|
||||
public double CeresScoreSoftLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Hard limit for Ceres scan match cost. When ceresScore exceeds this threshold,
|
||||
/// the scan-matched pose is considered unreliable: neither AddPose nor InsertIntoSubmap
|
||||
/// is called. The odometry prediction is used instead.
|
||||
/// Set to 0 to disable. Default: 0 (disabled).
|
||||
/// Must be >= CeresScoreSoftLimit when both are > 0.
|
||||
/// DEPRECATED: Use ProbabilityGridCeresScoreHardLimit / TsdfCeresScoreHardLimit instead.
|
||||
/// Kept as fallback when per-grid-type values are not set (both == 0).
|
||||
/// </summary>
|
||||
[JsonPropertyName("ceres_score_hard_limit")]
|
||||
public double CeresScoreHardLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// After this many consecutive hard-limit failures, forces creation of a new submap
|
||||
/// at the current odometry-predicted position. This breaks the deadlock when the robot
|
||||
/// enters a genuinely new area that cannot match any existing submap.
|
||||
/// Set to 0 to disable. Default: 5.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_consecutive_high_cost_before_new_submap")]
|
||||
public int MaxConsecutiveHighCostBeforeNewSubmap { get; set; }
|
||||
|
||||
public LocalTrajectoryBuilderOptions2D(
|
||||
double minRange = 0.0,
|
||||
double maxRange = 30.0,
|
||||
double minZ = -0.8f,
|
||||
double maxZ = 2.0,
|
||||
double missingDataRayLength = 5.0,
|
||||
int numAccumulatedRangeData = 1,
|
||||
double voxelFilterSize = 0.025f,
|
||||
bool useOnlineCorrelativeScanMatching = true,
|
||||
RealTimeCorrelativeScanMatcherOptions realTimeCorrelativeScanMatcherOptions = default,
|
||||
CeresScanMatcherOptions2D ceresScanMatcherOptions = default,
|
||||
MotionFilterOptions motionFilterOptions = default,
|
||||
SubmapsOptions2D submapsOptions = default,
|
||||
bool useImuData = false,
|
||||
AdaptiveVoxelFilterOptions adaptiveVoxelFilterOptions = default,
|
||||
AdaptiveVoxelFilterOptions loopClosureAdaptiveVoxelFilterOptions = default,
|
||||
double imuGravityTimeConstant = 10.0,
|
||||
PoseExtrapolatorOptions poseExtrapolatorOptions = default,
|
||||
RealTimeCorrelativeScanMatcherOptions initialPoseRealTimeCorrelativeScanMatcherOptions = default,
|
||||
CeresScanMatcherOptions2D initialPoseCeresScanMatcherOptions = default,
|
||||
bool provideConfidenceScore = false,
|
||||
double ceresScoreSoftLimit = 0,
|
||||
double ceresScoreHardLimit = 0,
|
||||
int maxConsecutiveHighCostBeforeNewSubmap = 5)
|
||||
{
|
||||
MinRange = minRange;
|
||||
MaxRange = maxRange;
|
||||
MinZ = minZ;
|
||||
MaxZ = maxZ;
|
||||
MissingDataRayLength = missingDataRayLength;
|
||||
NumAccumulatedRangeData = numAccumulatedRangeData;
|
||||
VoxelFilterSize = voxelFilterSize;
|
||||
UseOnlineCorrelativeScanMatching = useOnlineCorrelativeScanMatching;
|
||||
|
||||
// Set default values if not provided (default struct check)
|
||||
RealTimeCorrelativeScanMatcherOptions = realTimeCorrelativeScanMatcherOptions.Equals(default(RealTimeCorrelativeScanMatcherOptions))
|
||||
? new RealTimeCorrelativeScanMatcherOptions(linearSearchWindow: 0.1, angularSearchWindow: 0.2)
|
||||
: realTimeCorrelativeScanMatcherOptions;
|
||||
|
||||
CeresScanMatcherOptions = ceresScanMatcherOptions.Equals(default(CeresScanMatcherOptions2D))
|
||||
? new CeresScanMatcherOptions2D(occupiedSpaceWeight: 1.0, translationWeight: 10.0, rotationWeight: 1.0)
|
||||
: ceresScanMatcherOptions;
|
||||
|
||||
MotionFilterOptions = motionFilterOptions.Equals(default(MotionFilterOptions))
|
||||
? new MotionFilterOptions(maxTimeSeconds: 5.0, maxDistanceMeters: 0.2, maxAngleRadians: 0.1)
|
||||
: motionFilterOptions;
|
||||
|
||||
SubmapsOptions = submapsOptions.Equals(default(SubmapsOptions2D))
|
||||
? new SubmapsOptions2D(
|
||||
numRangeData: 90,
|
||||
new GridOptions2D(GridOptions2D.GridType.ProbabilityGrid, 0.05f),
|
||||
new RangeDataInserterOptions(RangeDataInserterOptions.RangeDataInserterType.ProbabilityGridInserter2D))
|
||||
: submapsOptions;
|
||||
|
||||
UseImuData = useImuData;
|
||||
|
||||
AdaptiveVoxelFilterOptions = adaptiveVoxelFilterOptions.Equals(default(AdaptiveVoxelFilterOptions))
|
||||
? new AdaptiveVoxelFilterOptions(maxLength: 0.3, minNumPoints: 250, maxRange: 50.0)
|
||||
: adaptiveVoxelFilterOptions;
|
||||
|
||||
LoopClosureAdaptiveVoxelFilterOptions = loopClosureAdaptiveVoxelFilterOptions.Equals(default(AdaptiveVoxelFilterOptions))
|
||||
? new AdaptiveVoxelFilterOptions(maxLength: 0.9, minNumPoints: 100, maxRange: 50.0)
|
||||
: loopClosureAdaptiveVoxelFilterOptions;
|
||||
|
||||
ImuGravityTimeConstant = imuGravityTimeConstant;
|
||||
|
||||
PoseExtrapolatorOptions = poseExtrapolatorOptions.Equals(default(PoseExtrapolatorOptions))
|
||||
? new PoseExtrapolatorOptions()
|
||||
: poseExtrapolatorOptions;
|
||||
|
||||
InitialPoseRealTimeCorrelativeScanMatcherOptions = initialPoseRealTimeCorrelativeScanMatcherOptions.Equals(default(RealTimeCorrelativeScanMatcherOptions))
|
||||
? new RealTimeCorrelativeScanMatcherOptions(linearSearchWindow: 0.5, angularSearchWindow: 0.5)
|
||||
: initialPoseRealTimeCorrelativeScanMatcherOptions;
|
||||
|
||||
InitialPoseCeresScanMatcherOptions = initialPoseCeresScanMatcherOptions.Equals(default(CeresScanMatcherOptions2D))
|
||||
? new CeresScanMatcherOptions2D(occupiedSpaceWeight: 20.0, translationWeight: 50.0, rotationWeight: 10.0)
|
||||
: initialPoseCeresScanMatcherOptions;
|
||||
|
||||
ProvideConfidenceScore = provideConfidenceScore;
|
||||
CeresScoreSoftLimit = ceresScoreSoftLimit;
|
||||
CeresScoreHardLimit = ceresScoreHardLimit;
|
||||
MaxConsecutiveHighCostBeforeNewSubmap = maxConsecutiveHighCostBeforeNewSubmap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Mapping.D3D;
|
||||
using CartographerSharp.Models.Sensor;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of local trajectory builder options for 3D.
|
||||
/// </summary>
|
||||
public struct LocalTrajectoryBuilderOptions3D
|
||||
{
|
||||
/// <summary>
|
||||
/// Rangefinder points outside these ranges will be dropped.
|
||||
/// </summary>
|
||||
[JsonPropertyName("min_range")]
|
||||
public double MinRange { get; set; }
|
||||
|
||||
[JsonPropertyName("max_range")]
|
||||
public double MaxRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of range data to accumulate into one unwarped, combined range data
|
||||
/// to use for scan matching.
|
||||
/// </summary>
|
||||
[JsonPropertyName("num_accumulated_range_data")]
|
||||
public int NumAccumulatedRangeData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Voxel filter that gets applied to the range data immediately after cropping.
|
||||
/// </summary>
|
||||
[JsonPropertyName("voxel_filter_size")]
|
||||
public double VoxelFilterSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Voxel filter used to compute a sparser point cloud for matching.
|
||||
/// </summary>
|
||||
[JsonPropertyName("high_resolution_adaptive_voxel_filter_options")]
|
||||
public AdaptiveVoxelFilterOptions? HighResolutionAdaptiveVoxelFilterOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("low_resolution_adaptive_voxel_filter_options")]
|
||||
public AdaptiveVoxelFilterOptions? LowResolutionAdaptiveVoxelFilterOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to solve the online scan matching first using the correlative scan
|
||||
/// matcher to generate a good starting point for Ceres.
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_online_correlative_scan_matching")]
|
||||
public bool UseOnlineCorrelativeScanMatching { get; set; }
|
||||
|
||||
[JsonPropertyName("real_time_correlative_scan_matcher_options")]
|
||||
public RealTimeCorrelativeScanMatcherOptions? RealTimeCorrelativeScanMatcherOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("ceres_scan_matcher_options")]
|
||||
public CeresScanMatcherOptions3D? CeresScanMatcherOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("motion_filter_options")]
|
||||
public MotionFilterOptions MotionFilterOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Time constant in seconds for the orientation moving average based on
|
||||
/// observed gravity via the IMU.
|
||||
/// </summary>
|
||||
[JsonPropertyName("imu_gravity_time_constant")]
|
||||
public double ImuGravityTimeConstant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of histogram buckets for the rotational scan matcher.
|
||||
/// </summary>
|
||||
[JsonPropertyName("rotational_histogram_size")]
|
||||
public int RotationalHistogramSize { get; set; }
|
||||
|
||||
[JsonPropertyName("pose_extrapolator_options")]
|
||||
public PoseExtrapolatorOptions PoseExtrapolatorOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("initial_poses")]
|
||||
public List<TimestampedTransform>? InitialPoses { get; set; }
|
||||
|
||||
[JsonPropertyName("initial_imu_data")]
|
||||
public List<Sensor.ImuData>? InitialImuData { get; set; }
|
||||
|
||||
[JsonPropertyName("submaps_options")]
|
||||
public SubmapsOptions3D SubmapsOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use Lidar intensities in Ceres Scan Matcher.
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_intensities")]
|
||||
public bool UseIntensities { get; set; }
|
||||
|
||||
public LocalTrajectoryBuilderOptions3D(
|
||||
double minRange = 0.0,
|
||||
double maxRange = 60.0,
|
||||
int numAccumulatedRangeData = 1,
|
||||
double voxelFilterSize = 0.15f,
|
||||
AdaptiveVoxelFilterOptions? highResolutionAdaptiveVoxelFilterOptions = null,
|
||||
AdaptiveVoxelFilterOptions? lowResolutionAdaptiveVoxelFilterOptions = null,
|
||||
bool useOnlineCorrelativeScanMatching = false,
|
||||
RealTimeCorrelativeScanMatcherOptions? realTimeCorrelativeScanMatcherOptions = null,
|
||||
CeresScanMatcherOptions3D? ceresScanMatcherOptions = null,
|
||||
MotionFilterOptions? motionFilterOptions = null,
|
||||
double imuGravityTimeConstant = 10.0,
|
||||
int rotationalHistogramSize = 120,
|
||||
PoseExtrapolatorOptions? poseExtrapolatorOptions = null,
|
||||
List<TimestampedTransform>? initialPoses = null,
|
||||
List<Sensor.ImuData>? initialImuData = null,
|
||||
SubmapsOptions3D? submapsOptions = null,
|
||||
bool useIntensities = false)
|
||||
{
|
||||
MinRange = minRange;
|
||||
MaxRange = maxRange;
|
||||
NumAccumulatedRangeData = numAccumulatedRangeData;
|
||||
VoxelFilterSize = voxelFilterSize;
|
||||
HighResolutionAdaptiveVoxelFilterOptions = highResolutionAdaptiveVoxelFilterOptions;
|
||||
LowResolutionAdaptiveVoxelFilterOptions = lowResolutionAdaptiveVoxelFilterOptions;
|
||||
UseOnlineCorrelativeScanMatching = useOnlineCorrelativeScanMatching;
|
||||
RealTimeCorrelativeScanMatcherOptions = realTimeCorrelativeScanMatcherOptions;
|
||||
CeresScanMatcherOptions = ceresScanMatcherOptions;
|
||||
MotionFilterOptions = motionFilterOptions ?? new MotionFilterOptions();
|
||||
ImuGravityTimeConstant = imuGravityTimeConstant;
|
||||
RotationalHistogramSize = rotationalHistogramSize;
|
||||
PoseExtrapolatorOptions = poseExtrapolatorOptions ?? new PoseExtrapolatorOptions();
|
||||
InitialPoses = initialPoses;
|
||||
InitialImuData = initialImuData;
|
||||
SubmapsOptions = submapsOptions ?? new SubmapsOptions3D();
|
||||
UseIntensities = useIntensities;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of map builder options.
|
||||
/// </summary>
|
||||
public struct MapBuilderOptions
|
||||
{
|
||||
[JsonPropertyName("use_trajectory_builder_2d")]
|
||||
public bool UseTrajectoryBuilder2D { get; set; }
|
||||
|
||||
[JsonPropertyName("use_trajectory_builder_3d")]
|
||||
public bool UseTrajectoryBuilder3D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of threads to use for background computations.
|
||||
/// </summary>
|
||||
[JsonPropertyName("num_background_threads")]
|
||||
public int NumBackgroundThreads { get; set; }
|
||||
|
||||
[JsonPropertyName("pose_graph_options")]
|
||||
public PoseGraphOptions PoseGraphOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sort sensor input independently for each trajectory.
|
||||
/// </summary>
|
||||
[JsonPropertyName("collate_by_trajectory")]
|
||||
public bool CollateByTrajectory { get; set; }
|
||||
|
||||
public MapBuilderOptions(
|
||||
bool useTrajectoryBuilder2D = true,
|
||||
bool useTrajectoryBuilder3D = false,
|
||||
int numBackgroundThreads = 4,
|
||||
PoseGraphOptions? poseGraphOptions = null,
|
||||
bool collateByTrajectory = false)
|
||||
{
|
||||
UseTrajectoryBuilder2D = useTrajectoryBuilder2D;
|
||||
UseTrajectoryBuilder3D = useTrajectoryBuilder3D;
|
||||
NumBackgroundThreads = numBackgroundThreads;
|
||||
PoseGraphOptions = poseGraphOptions ?? new PoseGraphOptions();
|
||||
CollateByTrajectory = collateByTrajectory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of map limits.
|
||||
/// </summary>
|
||||
public struct MapLimits
|
||||
{
|
||||
[JsonPropertyName("resolution")]
|
||||
public double Resolution { get; set; }
|
||||
|
||||
[JsonPropertyName("max")]
|
||||
public Vector2d Max { get; set; }
|
||||
|
||||
[JsonPropertyName("cell_limits")]
|
||||
public CellLimits CellLimits { get; set; }
|
||||
|
||||
public MapLimits(double resolution, Vector2d max, CellLimits cellLimits)
|
||||
{
|
||||
Resolution = resolution;
|
||||
Max = max;
|
||||
CellLimits = cellLimits;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of motion filter options.
|
||||
/// </summary>
|
||||
public struct MotionFilterOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Threshold above which range data is inserted based on time.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_time_seconds")]
|
||||
public double MaxTimeSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Threshold above which range data is inserted based on linear motion.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_distance_meters")]
|
||||
public double MaxDistanceMeters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Threshold above which range data is inserted based on rotational motion.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_angle_radians")]
|
||||
public double MaxAngleRadians { get; set; }
|
||||
|
||||
public MotionFilterOptions(double maxTimeSeconds, double maxDistanceMeters, double maxAngleRadians)
|
||||
{
|
||||
MaxTimeSeconds = maxTimeSeconds;
|
||||
MaxDistanceMeters = maxDistanceMeters;
|
||||
MaxAngleRadians = maxAngleRadians;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of normal estimation options for 2D.
|
||||
/// </summary>
|
||||
public struct NormalEstimationOptions2D
|
||||
{
|
||||
[JsonPropertyName("num_normal_samples")]
|
||||
public int NumNormalSamples { get; set; }
|
||||
|
||||
[JsonPropertyName("sample_radius")]
|
||||
public double SampleRadius { get; set; }
|
||||
|
||||
public NormalEstimationOptions2D(int numNormalSamples, double sampleRadius)
|
||||
{
|
||||
NumNormalSamples = numNormalSamples;
|
||||
SampleRadius = sampleRadius;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of optimization problem options.
|
||||
/// </summary>
|
||||
public struct OptimizationProblemOptions
|
||||
{
|
||||
[JsonPropertyName("huber_scale")]
|
||||
public double HuberScale { get; set; }
|
||||
|
||||
[JsonPropertyName("odometry_huber_scale")]
|
||||
public double OdometryHuberScale { get; set; }
|
||||
|
||||
[JsonPropertyName("local_slam_pose_huber_scale")]
|
||||
public double LocalSlamPoseHuberScale { get; set; }
|
||||
|
||||
[JsonPropertyName("odometry_translation_weight")]
|
||||
public double OdometryTranslationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("odometry_rotation_weight")]
|
||||
public double OdometryRotationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("local_slam_pose_translation_weight")]
|
||||
public double LocalSlamPoseTranslationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("local_slam_pose_rotation_weight")]
|
||||
public double LocalSlamPoseRotationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_pose_translation_weight")]
|
||||
public double FixedFramePoseTranslationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_pose_rotation_weight")]
|
||||
public double FixedFramePoseRotationWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_pose_use_tolerant_loss")]
|
||||
public bool FixedFramePoseUseTolerantLoss { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_pose_tolerant_loss_param_a")]
|
||||
public double FixedFramePoseTolerantLossParamA { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_pose_tolerant_loss_param_b")]
|
||||
public double FixedFramePoseTolerantLossParamB { get; set; }
|
||||
|
||||
[JsonPropertyName("log_solver_summary")]
|
||||
public bool LogSolverSummary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of iterations for the Ceres solver.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_num_iterations")]
|
||||
public int MaxNumIterations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Scaling parameter for the IMU acceleration term.
|
||||
/// </summary>
|
||||
[JsonPropertyName("acceleration_weight")]
|
||||
public double AccelerationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Scaling parameter for the IMU rotation term.
|
||||
/// </summary>
|
||||
[JsonPropertyName("rotation_weight")]
|
||||
public double RotationWeight { get; set; }
|
||||
|
||||
public OptimizationProblemOptions()
|
||||
{
|
||||
HuberScale = 1.0;
|
||||
OdometryHuberScale = 1.0;
|
||||
LocalSlamPoseHuberScale = 1.0;
|
||||
OdometryTranslationWeight = 1.0;
|
||||
OdometryRotationWeight = 1.0;
|
||||
LocalSlamPoseTranslationWeight = 1.0;
|
||||
LocalSlamPoseRotationWeight = 1.0;
|
||||
FixedFramePoseTranslationWeight = 1.0;
|
||||
FixedFramePoseRotationWeight = 1.0;
|
||||
FixedFramePoseUseTolerantLoss = false;
|
||||
FixedFramePoseTolerantLossParamA = 1.0;
|
||||
FixedFramePoseTolerantLossParamB = 1.0;
|
||||
LogSolverSummary = false;
|
||||
MaxNumIterations = 50; // Default for pose graph optimization
|
||||
AccelerationWeight = 8.0; // Default from C++ proto
|
||||
RotationWeight = 9.0; // Default from C++ proto
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of pose extrapolator options.
|
||||
/// </summary>
|
||||
public struct PoseExtrapolatorOptions
|
||||
{
|
||||
[JsonPropertyName("use_imu_based")]
|
||||
public bool UseImuBased { get; set; }
|
||||
|
||||
[JsonPropertyName("constant_velocity")]
|
||||
public ConstantVelocityPoseExtrapolatorOptions ConstantVelocity { get; set; }
|
||||
|
||||
[JsonPropertyName("imu_based")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public ImuBasedPoseExtrapolatorOptions? ImuBased { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Velocity threshold for detecting robot movement (m/s).
|
||||
/// Robot is considered "moving" if horizontal velocity exceeds this threshold.
|
||||
/// Default: 0.003 m/s (3 mm/s)
|
||||
/// </summary>
|
||||
[JsonPropertyName("velocity_threshold")]
|
||||
public double? VelocityThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Acceleration threshold for detecting IMU acceleration (m/s²).
|
||||
/// IMU is considered "accelerating" if horizontal acceleration exceeds this threshold.
|
||||
/// Default: 0.4 m/s²
|
||||
/// </summary>
|
||||
[JsonPropertyName("acceleration_threshold")]
|
||||
public double? AccelerationThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gravity deviation threshold for detecting vertical acceleration changes (m/s²).
|
||||
/// Used to detect changes in vertical acceleration (gravity deviation).
|
||||
/// Default: 0.1 m/s²
|
||||
/// </summary>
|
||||
[JsonPropertyName("gravity_deviation_threshold")]
|
||||
public double? GravityDeviationThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, use odometry pose directly at the time of range data instead of calculating velocity.
|
||||
/// This is useful when odometry data is accurate and reliable.
|
||||
/// When enabled, ExtrapolatePose will use the latest odometry data at or before the requested time,
|
||||
/// instead of extrapolating from the last pose using calculated velocity.
|
||||
/// Default: false (use velocity-based extrapolation)
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_odometry_directly")]
|
||||
public bool UseOdometryDirectly { get; set; }
|
||||
|
||||
public PoseExtrapolatorOptions(
|
||||
bool useImuBased = false,
|
||||
ConstantVelocityPoseExtrapolatorOptions? constantVelocity = null,
|
||||
ImuBasedPoseExtrapolatorOptions? imuBased = null,
|
||||
double? velocityThreshold = null,
|
||||
double? accelerationThreshold = null,
|
||||
double? gravityDeviationThreshold = null,
|
||||
bool useOdometryDirectly = false)
|
||||
{
|
||||
UseImuBased = useImuBased;
|
||||
ConstantVelocity = constantVelocity ?? new ConstantVelocityPoseExtrapolatorOptions();
|
||||
ImuBased = imuBased;
|
||||
VelocityThreshold = velocityThreshold;
|
||||
AccelerationThreshold = accelerationThreshold;
|
||||
GravityDeviationThreshold = gravityDeviationThreshold;
|
||||
UseOdometryDirectly = useOdometryDirectly;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constant velocity pose extrapolator options.
|
||||
/// </summary>
|
||||
public struct ConstantVelocityPoseExtrapolatorOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Time constant in seconds for the orientation moving average based on
|
||||
/// observed gravity via the IMU.
|
||||
/// </summary>
|
||||
[JsonPropertyName("imu_gravity_time_constant")]
|
||||
public double ImuGravityTimeConstant { get; set; }
|
||||
|
||||
[JsonPropertyName("pose_queue_duration")]
|
||||
public double PoseQueueDuration { get; set; }
|
||||
|
||||
public ConstantVelocityPoseExtrapolatorOptions(
|
||||
double imuGravityTimeConstant = 10.0,
|
||||
double poseQueueDuration = 0.001)
|
||||
{
|
||||
ImuGravityTimeConstant = imuGravityTimeConstant;
|
||||
PoseQueueDuration = poseQueueDuration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a pose graph.
|
||||
/// </summary>
|
||||
public struct PoseGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// Submap ID.
|
||||
/// </summary>
|
||||
public struct SubmapId
|
||||
{
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Submap index in the given trajectory.
|
||||
/// </summary>
|
||||
[JsonPropertyName("submap_index")]
|
||||
public int SubmapIndex { get; set; }
|
||||
|
||||
public SubmapId(int trajectoryId, int submapIndex)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
SubmapIndex = submapIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Node ID.
|
||||
/// </summary>
|
||||
public struct NodeId
|
||||
{
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Node index in the given trajectory.
|
||||
/// </summary>
|
||||
[JsonPropertyName("node_index")]
|
||||
public int NodeIndex { get; set; }
|
||||
|
||||
public NodeId(int trajectoryId, int nodeIndex)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
NodeIndex = nodeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constraint in the pose graph.
|
||||
/// </summary>
|
||||
public struct Constraint
|
||||
{
|
||||
/// <summary>
|
||||
/// Differentiates between intra-submap (where the range data was inserted
|
||||
/// into the submap) and inter-submap constraints (where the range data was
|
||||
/// not inserted into the submap).
|
||||
/// </summary>
|
||||
public enum Tag
|
||||
{
|
||||
IntraSubmap = 0,
|
||||
InterSubmap = 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Differentiates between enable state (condition to add to optimization)
|
||||
/// and disable state (do not use to optimize).
|
||||
/// </summary>
|
||||
public enum State
|
||||
{
|
||||
Enabled = 0,
|
||||
Disabled = 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Submap ID.
|
||||
/// </summary>
|
||||
[JsonPropertyName("submap_id")]
|
||||
public SubmapId SubmapId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Node ID.
|
||||
/// </summary>
|
||||
[JsonPropertyName("node_id")]
|
||||
public NodeId NodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pose of the node relative to submap, i.e. taking data from the node frame
|
||||
/// into the submap frame.
|
||||
/// </summary>
|
||||
[JsonPropertyName("relative_pose")]
|
||||
public Rigid3dProto RelativePose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Weight of the translational part of the constraint.
|
||||
/// </summary>
|
||||
[JsonPropertyName("translation_weight")]
|
||||
public double TranslationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Weight of the rotational part of the constraint.
|
||||
/// </summary>
|
||||
[JsonPropertyName("rotation_weight")]
|
||||
public double RotationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tag indicating constraint type.
|
||||
/// </summary>
|
||||
[JsonPropertyName("tag")]
|
||||
public Tag ConstraintTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Score of the constraint.
|
||||
/// </summary>
|
||||
[JsonPropertyName("score")]
|
||||
public double Score { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// State of the constraint (enabled or disabled).
|
||||
/// </summary>
|
||||
[JsonPropertyName("state")]
|
||||
public State ConstraintState { get; set; }
|
||||
|
||||
public Constraint(
|
||||
SubmapId submapId,
|
||||
NodeId nodeId,
|
||||
Rigid3dProto relativePose,
|
||||
double translationWeight,
|
||||
double rotationWeight,
|
||||
Tag constraintTag,
|
||||
double score = 0.0,
|
||||
State constraintState = State.Enabled)
|
||||
{
|
||||
SubmapId = submapId;
|
||||
NodeId = nodeId;
|
||||
RelativePose = relativePose;
|
||||
TranslationWeight = translationWeight;
|
||||
RotationWeight = rotationWeight;
|
||||
ConstraintTag = constraintTag;
|
||||
Score = score;
|
||||
ConstraintState = constraintState;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Landmark pose in the pose graph.
|
||||
/// </summary>
|
||||
public struct LandmarkPose
|
||||
{
|
||||
[JsonPropertyName("landmark_id")]
|
||||
public string LandmarkId { get; set; }
|
||||
|
||||
[JsonPropertyName("global_pose")]
|
||||
public Rigid3dProto GlobalPose { get; set; }
|
||||
|
||||
public LandmarkPose(string landmarkId, Rigid3dProto globalPose)
|
||||
{
|
||||
LandmarkId = landmarkId;
|
||||
GlobalPose = globalPose;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accurate submap in the pose graph.
|
||||
/// </summary>
|
||||
public struct AccurateSubmap
|
||||
{
|
||||
[JsonPropertyName("submap_id")]
|
||||
public SubmapId SubmapId { get; set; }
|
||||
|
||||
[JsonPropertyName("parent_id")]
|
||||
public SubmapId ParentId { get; set; }
|
||||
|
||||
[JsonPropertyName("pose")]
|
||||
public Rigid2dProto Pose { get; set; }
|
||||
|
||||
[JsonPropertyName("parent_relative_pose")]
|
||||
public Rigid2dProto ParentRelativePose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stop station in the accurate submap.
|
||||
/// </summary>
|
||||
public struct StopStation
|
||||
{
|
||||
public enum StopStationType
|
||||
{
|
||||
StartPoint = 0,
|
||||
StopPoint = 1
|
||||
}
|
||||
|
||||
[JsonPropertyName("pose")]
|
||||
public Rigid2dProto Pose { get; set; }
|
||||
|
||||
[JsonPropertyName("type")]
|
||||
public StopStationType Type { get; set; }
|
||||
|
||||
public StopStation(Rigid2dProto pose, StopStationType type)
|
||||
{
|
||||
Pose = pose;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("stop_stations")]
|
||||
public List<StopStation> StopStations { get; set; }
|
||||
|
||||
[JsonPropertyName("is_shelf")]
|
||||
public bool IsShelf { get; set; }
|
||||
|
||||
public AccurateSubmap(
|
||||
SubmapId submapId,
|
||||
SubmapId parentId,
|
||||
Rigid2dProto pose,
|
||||
Rigid2dProto parentRelativePose,
|
||||
List<StopStation>? stopStations = null,
|
||||
bool isShelf = false)
|
||||
{
|
||||
SubmapId = submapId;
|
||||
ParentId = parentId;
|
||||
Pose = pose;
|
||||
ParentRelativePose = parentRelativePose;
|
||||
StopStations = stopStations ?? new List<StopStation>();
|
||||
IsShelf = isShelf;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("constraint")]
|
||||
public List<Constraint> Constraints { get; set; }
|
||||
|
||||
[JsonPropertyName("trajectory")]
|
||||
public List<Trajectory> Trajectories { get; set; }
|
||||
|
||||
[JsonPropertyName("landmark_poses")]
|
||||
public List<LandmarkPose> LandmarkPoses { get; set; }
|
||||
|
||||
[JsonPropertyName("accurate_submaps")]
|
||||
public List<AccurateSubmap> AccurateSubmaps { get; set; }
|
||||
|
||||
[JsonPropertyName("transform_to_map")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Rigid3dProto? TransformToMap { get; set; }
|
||||
|
||||
public PoseGraph(
|
||||
List<Constraint>? constraints = null,
|
||||
List<Trajectory>? trajectories = null,
|
||||
List<LandmarkPose>? landmarkPoses = null,
|
||||
List<AccurateSubmap>? accurateSubmaps = null,
|
||||
Rigid3dProto? transformToMap = null)
|
||||
{
|
||||
Constraints = constraints ?? new List<Constraint>();
|
||||
Trajectories = trajectories ?? new List<Trajectory>();
|
||||
LandmarkPoses = landmarkPoses ?? new List<LandmarkPose>();
|
||||
AccurateSubmaps = accurateSubmaps ?? new List<AccurateSubmap>();
|
||||
TransformToMap = transformToMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of pose graph options.
|
||||
/// </summary>
|
||||
public struct PoseGraphOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Overlapping submaps trimmer options for 2D.
|
||||
/// </summary>
|
||||
public struct OverlappingSubmapsTrimmerOptions2D
|
||||
{
|
||||
[JsonPropertyName("fresh_submaps_count")]
|
||||
public int FreshSubmapsCount { get; set; }
|
||||
|
||||
[JsonPropertyName("min_covered_area")]
|
||||
public double MinCoveredArea { get; set; }
|
||||
|
||||
[JsonPropertyName("min_added_submaps_count")]
|
||||
public int MinAddedSubmapsCount { get; set; }
|
||||
|
||||
public OverlappingSubmapsTrimmerOptions2D(int freshSubmapsCount, double minCoveredArea, int minAddedSubmapsCount)
|
||||
{
|
||||
FreshSubmapsCount = freshSubmapsCount;
|
||||
MinCoveredArea = minCoveredArea;
|
||||
MinAddedSubmapsCount = minAddedSubmapsCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Online loop closure: If positive, will run the loop closure while the map is built.
|
||||
/// </summary>
|
||||
[JsonPropertyName("optimize_every_n_nodes")]
|
||||
public int OptimizeEveryNNodes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Weight used in the optimization problem for the translational component of
|
||||
/// non-loop-closure scan matcher constraints.
|
||||
/// </summary>
|
||||
[JsonPropertyName("matcher_translation_weight")]
|
||||
public double MatcherTranslationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Weight used in the optimization problem for the rotational component of
|
||||
/// non-loop-closure scan matcher constraints.
|
||||
/// </summary>
|
||||
[JsonPropertyName("matcher_rotation_weight")]
|
||||
public double MatcherRotationWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of iterations to use in 'optimization_problem_options' for the final optimization.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_num_final_iterations")]
|
||||
public int MaxNumFinalIterations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Rate at which we sample a single trajectory's nodes for global localization.
|
||||
/// </summary>
|
||||
[JsonPropertyName("global_sampling_ratio")]
|
||||
public double GlobalSamplingRatio { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to output histograms for the pose residuals.
|
||||
/// </summary>
|
||||
[JsonPropertyName("log_residual_histograms")]
|
||||
public bool LogResidualHistograms { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If for the duration specified by this option no global constraint has been
|
||||
/// added between two trajectories, loop closure searches will be performed
|
||||
/// globally rather than in a smaller search window.
|
||||
/// </summary>
|
||||
[JsonPropertyName("global_constraint_search_after_n_seconds")]
|
||||
public double GlobalConstraintSearchAfterNSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates the 'OverlappingSubmapsTrimmer2d' which trims submaps from the
|
||||
/// pose graph based on the area of overlap.
|
||||
/// </summary>
|
||||
[JsonPropertyName("overlapping_submaps_trimmer_2d")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public OverlappingSubmapsTrimmerOptions2D? OverlappingSubmapsTrimmer2D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Options for the constraint builder used to find loop closures.
|
||||
/// </summary>
|
||||
[JsonPropertyName("constraint_builder_options")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public ConstraintBuilderOptions? ConstraintBuilderOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Options for the optimization problem.
|
||||
/// </summary>
|
||||
[JsonPropertyName("optimization_problem_options")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public OptimizationProblemOptions? OptimizationProblemOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Max number of nodes to search for relocalization constraint (match C++ max_number_relocalization_nodes).
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_number_relocalization_nodes")]
|
||||
public int MaxNumberRelocalizationNodes { get; set; } = 12;
|
||||
|
||||
/// <summary>
|
||||
/// Enable loop closure detection within single trajectory.
|
||||
/// When enabled, uses MatchFullSubmap instead of Match for nodes that are
|
||||
/// far from their insertion submap but close to older finished submaps.
|
||||
/// This is an extension to C++ Cartographer which only supports multi-trajectory loop closure.
|
||||
/// </summary>
|
||||
[JsonPropertyName("enable_single_trajectory_loop_closure")]
|
||||
public bool EnableSingleTrajectoryLoopClosure { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Distance threshold (in meters) for triggering single-trajectory loop closure.
|
||||
/// If a node's initial_relative_pose distance to a finished submap exceeds this threshold,
|
||||
/// but the node is within search range, use MatchFullSubmap for global search.
|
||||
/// Only used when EnableSingleTrajectoryLoopClosure is true.
|
||||
/// </summary>
|
||||
[JsonPropertyName("single_trajectory_loop_closure_distance_threshold")]
|
||||
public double SingleTrajectoryLoopClosureDistanceThreshold { get; set; } = 3.0;
|
||||
|
||||
public PoseGraphOptions(
|
||||
int optimizeEveryNNodes = 90,
|
||||
double matcherTranslationWeight = 5e2,
|
||||
double matcherRotationWeight = 1.6e3,
|
||||
int maxNumFinalIterations = 200,
|
||||
double globalSamplingRatio = 0.003,
|
||||
bool logResidualHistograms = false,
|
||||
double globalConstraintSearchAfterNSeconds = 0.0,
|
||||
OverlappingSubmapsTrimmerOptions2D? overlappingSubmapsTrimmer2D = null,
|
||||
ConstraintBuilderOptions? constraintBuilderOptions = null,
|
||||
OptimizationProblemOptions? optimizationProblemOptions = null)
|
||||
{
|
||||
OptimizeEveryNNodes = optimizeEveryNNodes;
|
||||
MatcherTranslationWeight = matcherTranslationWeight;
|
||||
MatcherRotationWeight = matcherRotationWeight;
|
||||
MaxNumFinalIterations = maxNumFinalIterations;
|
||||
GlobalSamplingRatio = globalSamplingRatio;
|
||||
LogResidualHistograms = logResidualHistograms;
|
||||
GlobalConstraintSearchAfterNSeconds = globalConstraintSearchAfterNSeconds;
|
||||
OverlappingSubmapsTrimmer2D = overlappingSubmapsTrimmer2D;
|
||||
ConstraintBuilderOptions = constraintBuilderOptions;
|
||||
OptimizationProblemOptions = optimizationProblemOptions;
|
||||
MaxNumberRelocalizationNodes = 12;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a probability grid.
|
||||
/// </summary>
|
||||
public struct ProbabilityGrid
|
||||
{
|
||||
// Empty struct - no fields in proto definition
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of probability grid range data inserter options for 2D.
|
||||
/// </summary>
|
||||
public struct ProbabilityGridRangeDataInserterOptions2D
|
||||
{
|
||||
/// <summary>
|
||||
/// Probability change for a hit (this will be converted to odds and therefore
|
||||
/// must be greater than 0.5).
|
||||
/// </summary>
|
||||
[JsonPropertyName("hit_probability")]
|
||||
public double HitProbability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Probability change for a miss (this will be converted to odds and therefore
|
||||
/// must be less than 0.5).
|
||||
/// </summary>
|
||||
[JsonPropertyName("miss_probability")]
|
||||
public double MissProbability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If 'false', free space will not change the probabilities in the occupancy
|
||||
/// grid.
|
||||
/// </summary>
|
||||
[JsonPropertyName("insert_free_space")]
|
||||
public bool InsertFreeSpace { get; set; }
|
||||
|
||||
public ProbabilityGridRangeDataInserterOptions2D(
|
||||
double hitProbability,
|
||||
double missProbability,
|
||||
bool insertFreeSpace = true)
|
||||
{
|
||||
HitProbability = hitProbability;
|
||||
MissProbability = missProbability;
|
||||
InsertFreeSpace = insertFreeSpace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of range data inserter options.
|
||||
/// </summary>
|
||||
public struct RangeDataInserterOptions
|
||||
{
|
||||
public enum RangeDataInserterType
|
||||
{
|
||||
InvalidInserter = 0,
|
||||
ProbabilityGridInserter2D = 1,
|
||||
TsdfInserter2D = 2
|
||||
}
|
||||
|
||||
[JsonPropertyName("range_data_inserter_type")]
|
||||
public RangeDataInserterType RangeDataInserterTypeValue { get; set; }
|
||||
|
||||
[JsonPropertyName("probability_grid_range_data_inserter_options_2d")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public ProbabilityGridRangeDataInserterOptions2D? ProbabilityGridRangeDataInserterOptions2D { get; set; }
|
||||
|
||||
[JsonPropertyName("tsdf_range_data_inserter_options_2d")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public TSDFRangeDataInserterOptions2D? TsdfRangeDataInserterOptions2D { get; set; }
|
||||
|
||||
public RangeDataInserterOptions(
|
||||
RangeDataInserterType rangeDataInserterType,
|
||||
ProbabilityGridRangeDataInserterOptions2D? probabilityGridRangeDataInserterOptions2D = null,
|
||||
TSDFRangeDataInserterOptions2D? tsdfRangeDataInserterOptions2D = null)
|
||||
{
|
||||
RangeDataInserterTypeValue = rangeDataInserterType;
|
||||
ProbabilityGridRangeDataInserterOptions2D = probabilityGridRangeDataInserterOptions2D;
|
||||
TsdfRangeDataInserterOptions2D = tsdfRangeDataInserterOptions2D;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of real-time correlative scan matcher options.
|
||||
/// </summary>
|
||||
public struct RealTimeCorrelativeScanMatcherOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimum linear search window in which the best possible scan alignment
|
||||
/// will be found.
|
||||
/// </summary>
|
||||
[JsonPropertyName("linear_search_window")]
|
||||
public double LinearSearchWindow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum angular search window in which the best possible scan alignment
|
||||
/// will be found.
|
||||
/// </summary>
|
||||
[JsonPropertyName("angular_search_window")]
|
||||
public double AngularSearchWindow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Weights applied to each part of the score.
|
||||
/// </summary>
|
||||
[JsonPropertyName("translation_delta_cost_weight")]
|
||||
public double TranslationDeltaCostWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("rotation_delta_cost_weight")]
|
||||
public double RotationDeltaCostWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of threads to use for parallel candidate scoring.
|
||||
/// If 0 or 1, scoring will be done sequentially.
|
||||
/// </summary>
|
||||
[JsonPropertyName("num_threads")]
|
||||
public int NumThreads { get; set; } = 1;
|
||||
|
||||
public RealTimeCorrelativeScanMatcherOptions(
|
||||
double linearSearchWindow,
|
||||
double angularSearchWindow,
|
||||
double translationDeltaCostWeight = 1.0,
|
||||
double rotationDeltaCostWeight = 1.0,
|
||||
int numThreads = 1)
|
||||
{
|
||||
LinearSearchWindow = linearSearchWindow;
|
||||
AngularSearchWindow = angularSearchWindow;
|
||||
TranslationDeltaCostWeight = translationDeltaCostWeight;
|
||||
RotationDeltaCostWeight = rotationDeltaCostWeight;
|
||||
NumThreads = numThreads;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Sensor;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Header of the serialization format. At the moment it only contains the version of the format.
|
||||
/// </summary>
|
||||
public struct SerializationHeader
|
||||
{
|
||||
[JsonPropertyName("format_version")]
|
||||
public uint FormatVersion { get; set; }
|
||||
|
||||
public SerializationHeader(uint formatVersion)
|
||||
{
|
||||
FormatVersion = formatVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a Submap with ID.
|
||||
/// </summary>
|
||||
public struct Submap
|
||||
{
|
||||
[JsonPropertyName("submap_id")]
|
||||
public PoseGraph.SubmapId SubmapId { get; set; }
|
||||
|
||||
[JsonPropertyName("submap_2d")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Submap2D? Submap2D { get; set; }
|
||||
|
||||
[JsonPropertyName("submap_3d")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Submap3D? Submap3D { get; set; }
|
||||
|
||||
public Submap(PoseGraph.SubmapId submapId, Submap2D? submap2D = null, Submap3D? submap3D = null)
|
||||
{
|
||||
SubmapId = submapId;
|
||||
Submap2D = submap2D;
|
||||
Submap3D = submap3D;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a Node with ID.
|
||||
/// </summary>
|
||||
public struct Node
|
||||
{
|
||||
[JsonPropertyName("node_id")]
|
||||
public PoseGraph.NodeId NodeId { get; set; }
|
||||
|
||||
[JsonPropertyName("node_data")]
|
||||
public TrajectoryNodeData NodeData { get; set; }
|
||||
|
||||
public Node(PoseGraph.NodeId nodeId, TrajectoryNodeData nodeData)
|
||||
{
|
||||
NodeId = nodeId;
|
||||
NodeData = nodeData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IMU data with trajectory ID for serialization.
|
||||
/// </summary>
|
||||
public struct SerializedImuData
|
||||
{
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
[JsonPropertyName("imu_data")]
|
||||
public Sensor.ImuData ImuDataValue { get; set; }
|
||||
|
||||
public SerializedImuData(int trajectoryId, Sensor.ImuData imuData)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
ImuDataValue = imuData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Odometry data with trajectory ID for serialization.
|
||||
/// </summary>
|
||||
public struct SerializedOdometryData
|
||||
{
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
[JsonPropertyName("odometry_data")]
|
||||
public Sensor.OdometryData OdometryDataValue { get; set; }
|
||||
|
||||
public SerializedOdometryData(int trajectoryId, Sensor.OdometryData odometryData)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
OdometryDataValue = odometryData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixed frame pose data with trajectory ID for serialization.
|
||||
/// </summary>
|
||||
public struct SerializedFixedFramePoseData
|
||||
{
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_pose_data")]
|
||||
public Sensor.FixedFramePoseData FixedFramePoseDataValue { get; set; }
|
||||
|
||||
public SerializedFixedFramePoseData(int trajectoryId, Sensor.FixedFramePoseData fixedFramePoseData)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
FixedFramePoseDataValue = fixedFramePoseData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Landmark data with trajectory ID for serialization.
|
||||
/// </summary>
|
||||
public struct SerializedLandmarkData
|
||||
{
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
[JsonPropertyName("landmark_data")]
|
||||
public Sensor.LandmarkData LandmarkDataValue { get; set; }
|
||||
|
||||
public SerializedLandmarkData(int trajectoryId, Sensor.LandmarkData landmarkData)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
LandmarkDataValue = landmarkData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trajectory data for serialization.
|
||||
/// </summary>
|
||||
public struct SerializedTrajectoryData
|
||||
{
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
[JsonPropertyName("gravity_constant")]
|
||||
public double GravityConstant { get; set; }
|
||||
|
||||
[JsonPropertyName("imu_calibration")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Quaterniond? ImuCalibration { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_origin_in_map")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Rigid3dProto? FixedFrameOriginInMap { get; set; }
|
||||
|
||||
public SerializedTrajectoryData(int trajectoryId, double gravityConstant, Quaterniond? imuCalibration = null, Rigid3dProto? fixedFrameOriginInMap = null)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
GravityConstant = gravityConstant;
|
||||
ImuCalibration = imuCalibration;
|
||||
FixedFrameOriginInMap = fixedFrameOriginInMap;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop station data for serialization.
|
||||
/// </summary>
|
||||
public struct StopStationData
|
||||
{
|
||||
[JsonPropertyName("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[JsonPropertyName("time")]
|
||||
public long Time { get; set; }
|
||||
|
||||
[JsonPropertyName("local_pose")]
|
||||
public Rigid3dProto LocalPose { get; set; }
|
||||
|
||||
public StopStationData(int id, long time, Rigid3dProto localPose)
|
||||
{
|
||||
Id = id;
|
||||
Time = time;
|
||||
LocalPose = localPose;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accurate submap for serialization (different from PoseGraph.AccurateSubmap).
|
||||
/// </summary>
|
||||
public struct SerializedAccurateSubmap
|
||||
{
|
||||
[JsonPropertyName("submap")]
|
||||
public Submap Submap { get; set; }
|
||||
|
||||
[JsonPropertyName("stop_stations")]
|
||||
public List<StopStationData> StopStations { get; set; }
|
||||
|
||||
public SerializedAccurateSubmap(Submap submap, List<StopStationData>? stopStations = null)
|
||||
{
|
||||
Submap = submap;
|
||||
StopStations = stopStations ?? new List<StopStationData>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialized data container (oneof in proto).
|
||||
/// </summary>
|
||||
public struct SerializedData
|
||||
{
|
||||
[JsonPropertyName("serialization_header")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public SerializationHeader? SerializationHeader { get; set; }
|
||||
|
||||
[JsonPropertyName("pose_graph")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public PoseGraph? PoseGraph { get; set; }
|
||||
|
||||
[JsonPropertyName("all_trajectory_builder_options")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public AllTrajectoryBuilderOptions? AllTrajectoryBuilderOptions { get; set; }
|
||||
|
||||
[JsonPropertyName("submap")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Submap? Submap { get; set; }
|
||||
|
||||
[JsonPropertyName("node")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Node? Node { get; set; }
|
||||
|
||||
[JsonPropertyName("trajectory_data")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public SerializedTrajectoryData? SerializedTrajectoryData { get; set; }
|
||||
|
||||
[JsonPropertyName("imu_data")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public SerializedImuData? ImuData { get; set; }
|
||||
|
||||
[JsonPropertyName("odometry_data")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public SerializedOdometryData? OdometryData { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_pose_data")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public SerializedFixedFramePoseData? FixedFramePoseData { get; set; }
|
||||
|
||||
[JsonPropertyName("landmark_data")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public SerializedLandmarkData? LandmarkData { get; set; }
|
||||
|
||||
[JsonPropertyName("accurate_submap")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public SerializedAccurateSubmap? AccurateSubmap { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Active area of the submap.
|
||||
/// </summary>
|
||||
public struct ActiveArea
|
||||
{
|
||||
[JsonPropertyName("min_x")]
|
||||
public double MinX { get; set; }
|
||||
|
||||
[JsonPropertyName("min_y")]
|
||||
public double MinY { get; set; }
|
||||
|
||||
[JsonPropertyName("max_x")]
|
||||
public double MaxX { get; set; }
|
||||
|
||||
[JsonPropertyName("max_y")]
|
||||
public double MaxY { get; set; }
|
||||
|
||||
[JsonPropertyName("origin")]
|
||||
public Rigid3dProto Origin { get; set; }
|
||||
|
||||
public ActiveArea(double minX, double minY, double maxX, double maxY, Rigid3dProto origin)
|
||||
{
|
||||
MinX = minX;
|
||||
MinY = minY;
|
||||
MaxX = maxX;
|
||||
MaxY = maxY;
|
||||
Origin = origin;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialized state of a Submap2D.
|
||||
/// </summary>
|
||||
public struct Submap2D
|
||||
{
|
||||
[JsonPropertyName("local_pose")]
|
||||
public Rigid3dProto LocalPose { get; set; }
|
||||
|
||||
[JsonPropertyName("num_range_data")]
|
||||
public int NumRangeData { get; set; }
|
||||
|
||||
[JsonPropertyName("finished")]
|
||||
public bool Finished { get; set; }
|
||||
|
||||
[JsonPropertyName("grid")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Grid2D? Grid { get; set; }
|
||||
|
||||
[JsonPropertyName("active_area")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public ActiveArea? ActiveArea { get; set; }
|
||||
|
||||
[JsonPropertyName("merged_from_others")]
|
||||
public bool MergedFromOthers { get; set; }
|
||||
|
||||
public Submap2D(
|
||||
Rigid3dProto localPose,
|
||||
int numRangeData,
|
||||
bool finished,
|
||||
Grid2D? grid = null,
|
||||
ActiveArea? activeArea = null,
|
||||
bool mergedFromOthers = false)
|
||||
{
|
||||
LocalPose = localPose;
|
||||
NumRangeData = numRangeData;
|
||||
Finished = finished;
|
||||
Grid = grid;
|
||||
ActiveArea = activeArea;
|
||||
MergedFromOthers = mergedFromOthers;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialized state of a Submap3D.
|
||||
/// </summary>
|
||||
public struct Submap3D
|
||||
{
|
||||
[JsonPropertyName("local_pose")]
|
||||
public Rigid3dProto LocalPose { get; set; }
|
||||
|
||||
[JsonPropertyName("num_range_data")]
|
||||
public int NumRangeData { get; set; }
|
||||
|
||||
[JsonPropertyName("finished")]
|
||||
public bool Finished { get; set; }
|
||||
|
||||
[JsonPropertyName("high_resolution_hybrid_grid")]
|
||||
public HybridGrid HighResolutionHybridGrid { get; set; }
|
||||
|
||||
[JsonPropertyName("low_resolution_hybrid_grid")]
|
||||
public HybridGrid LowResolutionHybridGrid { get; set; }
|
||||
|
||||
[JsonPropertyName("rotational_scan_matcher_histogram")]
|
||||
public List<double> RotationalScanMatcherHistogram { get; set; }
|
||||
|
||||
public Submap3D(
|
||||
Rigid3dProto localPose,
|
||||
int numRangeData,
|
||||
bool finished,
|
||||
HybridGrid highResolutionHybridGrid,
|
||||
HybridGrid lowResolutionHybridGrid,
|
||||
List<double>? rotationalScanMatcherHistogram = null)
|
||||
{
|
||||
LocalPose = localPose;
|
||||
NumRangeData = numRangeData;
|
||||
Finished = finished;
|
||||
HighResolutionHybridGrid = highResolutionHybridGrid;
|
||||
LowResolutionHybridGrid = lowResolutionHybridGrid;
|
||||
RotationalScanMatcherHistogram = rotationalScanMatcherHistogram ?? new List<double>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of submap query response.
|
||||
/// </summary>
|
||||
public struct SubmapQuery
|
||||
{
|
||||
public struct Response
|
||||
{
|
||||
[JsonPropertyName("submap_version")]
|
||||
public int SubmapVersion { get; set; }
|
||||
|
||||
[JsonPropertyName("textures")]
|
||||
public List<Texture> Textures { get; set; }
|
||||
|
||||
[JsonPropertyName("error_message")]
|
||||
public string? ErrorMessage { get; set; }
|
||||
|
||||
public Response(int submapVersion, List<Texture> textures, string? errorMessage = null)
|
||||
{
|
||||
SubmapVersion = submapVersion;
|
||||
Textures = textures ?? new List<Texture>();
|
||||
ErrorMessage = errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Texture
|
||||
{
|
||||
[JsonPropertyName("cells")]
|
||||
public List<byte> Cells { get; set; }
|
||||
|
||||
[JsonPropertyName("width")]
|
||||
public int Width { get; set; }
|
||||
|
||||
[JsonPropertyName("height")]
|
||||
public int Height { get; set; }
|
||||
|
||||
[JsonPropertyName("resolution")]
|
||||
public double Resolution { get; set; }
|
||||
|
||||
[JsonPropertyName("slice_pose")]
|
||||
public Transform.Rigid3dProto SlicePose { get; set; }
|
||||
|
||||
public Texture(
|
||||
List<byte> cells,
|
||||
int width,
|
||||
int height,
|
||||
double resolution,
|
||||
Transform.Rigid3dProto slicePose)
|
||||
{
|
||||
Cells = cells ?? new List<byte>();
|
||||
Width = width;
|
||||
Height = height;
|
||||
Resolution = resolution;
|
||||
SlicePose = slicePose;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of submaps options for 2D.
|
||||
/// </summary>
|
||||
public struct SubmapsOptions2D
|
||||
{
|
||||
/// <summary>
|
||||
/// Number of range data before adding a new submap. Each submap will get twice
|
||||
/// the number of range data inserted: First for initialization without being
|
||||
/// matched against, then while being matched.
|
||||
/// </summary>
|
||||
[JsonPropertyName("num_range_data")]
|
||||
public int NumRangeData { get; set; }
|
||||
|
||||
[JsonPropertyName("grid_options_2d")]
|
||||
public GridOptions2D GridOptions2D { get; set; }
|
||||
|
||||
[JsonPropertyName("range_data_inserter_options")]
|
||||
public RangeDataInserterOptions RangeDataInserterOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional high resolution grid options for fine-grained Ceres scan matching.
|
||||
/// When set, a second grid at higher resolution is maintained per submap and
|
||||
/// passed to CeresScanMatcher2D for more precise wall alignment.
|
||||
/// </summary>
|
||||
[JsonPropertyName("high_res_grid_options_2d")]
|
||||
public GridOptions2D? HighResGridOptions2D { get; set; }
|
||||
|
||||
public SubmapsOptions2D(
|
||||
int numRangeData,
|
||||
GridOptions2D gridOptions2D,
|
||||
RangeDataInserterOptions rangeDataInserterOptions,
|
||||
GridOptions2D? highResGridOptions2D = null)
|
||||
{
|
||||
NumRangeData = numRangeData;
|
||||
GridOptions2D = gridOptions2D;
|
||||
RangeDataInserterOptions = rangeDataInserterOptions;
|
||||
HighResGridOptions2D = highResGridOptions2D;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of TSDF2D grid.
|
||||
/// </summary>
|
||||
public struct TSDF2D
|
||||
{
|
||||
[JsonPropertyName("truncation_distance")]
|
||||
public double TruncationDistance { get; set; }
|
||||
|
||||
[JsonPropertyName("max_weight")]
|
||||
public double MaxWeight { get; set; }
|
||||
|
||||
[JsonPropertyName("weight_cells")]
|
||||
public List<int> WeightCells { get; set; }
|
||||
|
||||
public TSDF2D(double truncationDistance, double maxWeight, List<int>? weightCells = null)
|
||||
{
|
||||
TruncationDistance = truncationDistance;
|
||||
MaxWeight = maxWeight;
|
||||
WeightCells = weightCells ?? new List<int>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of TSDF range data inserter options for 2D.
|
||||
/// </summary>
|
||||
public struct TSDFRangeDataInserterOptions2D
|
||||
{
|
||||
/// <summary>
|
||||
/// Distance to the surface within the signed distance function is evaluated.
|
||||
/// </summary>
|
||||
[JsonPropertyName("truncation_distance")]
|
||||
public double TruncationDistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum weight that can be stored in a cell.
|
||||
/// </summary>
|
||||
[JsonPropertyName("maximum_weight")]
|
||||
public double MaximumWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables updating cells between the sensor origin and the range observation as free space.
|
||||
/// </summary>
|
||||
[JsonPropertyName("update_free_space")]
|
||||
public bool UpdateFreeSpace { get; set; }
|
||||
|
||||
[JsonPropertyName("normal_estimation_options")]
|
||||
public NormalEstimationOptions2D NormalEstimationOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Project the distance between the updated cell and the range observation to the estimated scan normal.
|
||||
/// </summary>
|
||||
[JsonPropertyName("project_sdf_distance_to_scan_normal")]
|
||||
public bool ProjectSdfDistanceToScanNormal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Update weight is scaled with 1/distance(origin,hit)^range_exponent.
|
||||
/// </summary>
|
||||
[JsonPropertyName("update_weight_range_exponent")]
|
||||
public int UpdateWeightRangeExponent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Kernel bandwidth of the weight factor based on the angle between scan normal and ray.
|
||||
/// </summary>
|
||||
[JsonPropertyName("update_weight_angle_scan_normal_to_ray_kernel_bandwidth")]
|
||||
public double UpdateWeightAngleScanNormalToRayKernelBandwidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Kernel bandwidth of the weight factor based on the distance between cell and scan observation.
|
||||
/// </summary>
|
||||
[JsonPropertyName("update_weight_distance_cell_to_hit_kernel_bandwidth")]
|
||||
public double UpdateWeightDistanceCellToHitKernelBandwidth { get; set; }
|
||||
|
||||
public TSDFRangeDataInserterOptions2D(
|
||||
double truncationDistance,
|
||||
double maximumWeight,
|
||||
bool updateFreeSpace = false,
|
||||
NormalEstimationOptions2D normalEstimationOptions = default,
|
||||
bool projectSdfDistanceToScanNormal = false,
|
||||
int updateWeightRangeExponent = 0,
|
||||
double updateWeightAngleScanNormalToRayKernelBandwidth = 0.0,
|
||||
double updateWeightDistanceCellToHitKernelBandwidth = 0.0)
|
||||
{
|
||||
TruncationDistance = truncationDistance;
|
||||
MaximumWeight = maximumWeight;
|
||||
UpdateFreeSpace = updateFreeSpace;
|
||||
NormalEstimationOptions = normalEstimationOptions;
|
||||
ProjectSdfDistanceToScanNormal = projectSdfDistanceToScanNormal;
|
||||
UpdateWeightRangeExponent = updateWeightRangeExponent;
|
||||
UpdateWeightAngleScanNormalToRayKernelBandwidth = updateWeightAngleScanNormalToRayKernelBandwidth;
|
||||
UpdateWeightDistanceCellToHitKernelBandwidth = updateWeightDistanceCellToHitKernelBandwidth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a trajectory.
|
||||
/// </summary>
|
||||
public struct Trajectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Node within a trajectory.
|
||||
/// </summary>
|
||||
public struct Node
|
||||
{
|
||||
/// <summary>
|
||||
/// Index of this node within its trajectory.
|
||||
/// </summary>
|
||||
[JsonPropertyName("node_index")]
|
||||
public int NodeIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp of this node.
|
||||
/// </summary>
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Transform from tracking to global map frame.
|
||||
/// </summary>
|
||||
[JsonPropertyName("pose")]
|
||||
public Rigid3dProto Pose { get; set; }
|
||||
|
||||
public Node(int nodeIndex, long timestamp, Rigid3dProto pose)
|
||||
{
|
||||
NodeIndex = nodeIndex;
|
||||
Timestamp = timestamp;
|
||||
Pose = pose;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Submap within a trajectory.
|
||||
/// </summary>
|
||||
public struct Submap
|
||||
{
|
||||
/// <summary>
|
||||
/// Index of this submap within its trajectory.
|
||||
/// </summary>
|
||||
[JsonPropertyName("submap_index")]
|
||||
public int SubmapIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Transform from submap to global map frame.
|
||||
/// </summary>
|
||||
[JsonPropertyName("pose")]
|
||||
public Rigid3dProto Pose { get; set; }
|
||||
|
||||
public Submap(int submapIndex, Rigid3dProto pose)
|
||||
{
|
||||
SubmapIndex = submapIndex;
|
||||
Pose = pose;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ID of this trajectory.
|
||||
/// </summary>
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Time-ordered sequence of Nodes.
|
||||
/// </summary>
|
||||
[JsonPropertyName("node")]
|
||||
public List<Node> Nodes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Submaps associated with the trajectory.
|
||||
/// </summary>
|
||||
[JsonPropertyName("submap")]
|
||||
public List<Submap> Submaps { get; set; }
|
||||
|
||||
public Trajectory(int trajectoryId, List<Node>? nodes = null, List<Submap>? submaps = null)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
Nodes = nodes ?? new List<Node>();
|
||||
Submaps = submaps ?? new List<Submap>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of initial trajectory pose.
|
||||
/// </summary>
|
||||
public struct InitialTrajectoryPose
|
||||
{
|
||||
[JsonPropertyName("relative_pose")]
|
||||
public Rigid3dProto RelativePose { get; set; }
|
||||
|
||||
[JsonPropertyName("to_trajectory_id")]
|
||||
public int ToTrajectoryId { get; set; }
|
||||
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; }
|
||||
|
||||
public InitialTrajectoryPose(Rigid3dProto relativePose, int toTrajectoryId, long timestamp)
|
||||
{
|
||||
RelativePose = relativePose;
|
||||
ToTrajectoryId = toTrajectoryId;
|
||||
Timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of trajectory builder options.
|
||||
/// Note: LocalTrajectoryBuilderOptions2D and LocalTrajectoryBuilderOptions3D
|
||||
/// are complex types that will be implemented in later phases.
|
||||
/// </summary>
|
||||
public struct TrajectoryBuilderOptions(
|
||||
System.Text.Json.JsonElement? trajectoryBuilder2DOptions = null,
|
||||
System.Text.Json.JsonElement? trajectoryBuilder3DOptions = null,
|
||||
InitialTrajectoryPose? initialTrajectoryPose = null,
|
||||
TrajectoryBuilderOptions.PureLocalizationTrimmerOptions? pureLocalizationTrimmer = null,
|
||||
bool collateFixedFrame = false,
|
||||
bool collateLandmarks = false,
|
||||
MotionFilterOptions? poseGraphOdometryMotionFilter = null)
|
||||
{
|
||||
// Note: These will be implemented as separate proto files in later phases
|
||||
// For now, we use JsonElement to handle them as raw JSON
|
||||
[JsonPropertyName("trajectory_builder_2d_options")]
|
||||
public System.Text.Json.JsonElement? TrajectoryBuilder2DOptions { get; set; } = trajectoryBuilder2DOptions;
|
||||
|
||||
[JsonPropertyName("trajectory_builder_3d_options")]
|
||||
public System.Text.Json.JsonElement? TrajectoryBuilder3DOptions { get; set; } = trajectoryBuilder3DOptions;
|
||||
|
||||
[JsonPropertyName("initial_trajectory_pose")]
|
||||
public InitialTrajectoryPose? InitialTrajectoryPose { get; set; } = initialTrajectoryPose;
|
||||
|
||||
[JsonPropertyName("pure_localization")]
|
||||
[System.Obsolete("Deprecated")]
|
||||
public bool PureLocalization { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pure localization trimmer options.
|
||||
/// </summary>
|
||||
public struct PureLocalizationTrimmerOptions
|
||||
{
|
||||
[JsonPropertyName("max_submaps_to_keep")]
|
||||
public int MaxSubmapsToKeep { get; set; }
|
||||
|
||||
public PureLocalizationTrimmerOptions(int maxSubmapsToKeep)
|
||||
{
|
||||
MaxSubmapsToKeep = maxSubmapsToKeep;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("pure_localization_trimmer")]
|
||||
public PureLocalizationTrimmerOptions? PureLocalizationTrimmer { get; set; } = pureLocalizationTrimmer;
|
||||
|
||||
[JsonPropertyName("collate_fixed_frame")]
|
||||
public bool CollateFixedFrame { get; set; } = collateFixedFrame;
|
||||
|
||||
[JsonPropertyName("collate_landmarks")]
|
||||
public bool CollateLandmarks { get; set; } = collateLandmarks;
|
||||
|
||||
[JsonPropertyName("pose_graph_odometry_motion_filter")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public MotionFilterOptions? PoseGraphOdometryMotionFilter { get; set; } = poseGraphOdometryMotionFilter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of sensor ID.
|
||||
/// </summary>
|
||||
public struct SensorId
|
||||
{
|
||||
/// <summary>
|
||||
/// Sensor type enumeration.
|
||||
/// </summary>
|
||||
public enum SensorType
|
||||
{
|
||||
Range = 0,
|
||||
Imu = 1,
|
||||
Odometry = 2,
|
||||
FixedFramePose = 3,
|
||||
Landmark = 4,
|
||||
LocalSlamResult = 5
|
||||
}
|
||||
|
||||
[JsonPropertyName("type")]
|
||||
public SensorType Type { get; set; }
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
public SensorId(SensorType type, string id)
|
||||
{
|
||||
Type = type;
|
||||
Id = id;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of trajectory builder options with sensor IDs.
|
||||
/// </summary>
|
||||
public struct TrajectoryBuilderOptionsWithSensorIds
|
||||
{
|
||||
[JsonPropertyName("sensor_id")]
|
||||
public List<SensorId> SensorIds { get; set; }
|
||||
|
||||
[JsonPropertyName("trajectory_builder_options")]
|
||||
public TrajectoryBuilderOptions TrajectoryBuilderOptions { get; set; }
|
||||
|
||||
public TrajectoryBuilderOptionsWithSensorIds(
|
||||
List<SensorId>? sensorIds = null,
|
||||
TrajectoryBuilderOptions trajectoryBuilderOptions = default)
|
||||
{
|
||||
SensorIds = sensorIds ?? new List<SensorId>();
|
||||
TrajectoryBuilderOptions = trajectoryBuilderOptions;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of all trajectory builder options.
|
||||
/// </summary>
|
||||
public struct AllTrajectoryBuilderOptions
|
||||
{
|
||||
[JsonPropertyName("options_with_sensor_ids")]
|
||||
public List<TrajectoryBuilderOptionsWithSensorIds> OptionsWithSensorIds { get; set; }
|
||||
|
||||
public AllTrajectoryBuilderOptions(List<TrajectoryBuilderOptionsWithSensorIds>? optionsWithSensorIds = null)
|
||||
{
|
||||
OptionsWithSensorIds = optionsWithSensorIds ?? new List<TrajectoryBuilderOptionsWithSensorIds>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of trajectory data.
|
||||
/// </summary>
|
||||
public struct TrajectoryData
|
||||
{
|
||||
[JsonPropertyName("trajectory_id")]
|
||||
public int TrajectoryId { get; set; }
|
||||
|
||||
[JsonPropertyName("gravity_constant")]
|
||||
public double GravityConstant { get; set; }
|
||||
|
||||
[JsonPropertyName("imu_calibration")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Quaterniond? ImuCalibration { get; set; }
|
||||
|
||||
[JsonPropertyName("fixed_frame_origin_in_map")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Rigid3dProto? FixedFrameOriginInMap { get; set; }
|
||||
|
||||
public TrajectoryData(
|
||||
int trajectoryId,
|
||||
double gravityConstant = 9.8,
|
||||
Quaterniond? imuCalibration = null,
|
||||
Rigid3dProto? fixedFrameOriginInMap = null)
|
||||
{
|
||||
TrajectoryId = trajectoryId;
|
||||
GravityConstant = gravityConstant;
|
||||
ImuCalibration = imuCalibration;
|
||||
FixedFrameOriginInMap = fixedFrameOriginInMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2017 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using CartographerSharp.Models.Sensor;
|
||||
using CartographerSharp.Models.Transform;
|
||||
|
||||
namespace CartographerSharp.Models.Mapping;
|
||||
|
||||
/// <summary>
|
||||
/// Serialized state of a mapping::TrajectoryNode::Data.
|
||||
/// </summary>
|
||||
public struct TrajectoryNodeData
|
||||
{
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; }
|
||||
|
||||
[JsonPropertyName("gravity_alignment")]
|
||||
public Quaterniond GravityAlignment { get; set; }
|
||||
|
||||
[JsonPropertyName("filtered_gravity_aligned_point_cloud")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public CompressedPointCloud? FilteredGravityAlignedPointCloud { get; set; }
|
||||
|
||||
[JsonPropertyName("high_resolution_point_cloud")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public CompressedPointCloud? HighResolutionPointCloud { get; set; }
|
||||
|
||||
[JsonPropertyName("low_resolution_point_cloud")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public CompressedPointCloud? LowResolutionPointCloud { get; set; }
|
||||
|
||||
[JsonPropertyName("rotational_scan_matcher_histogram")]
|
||||
public List<double>? RotationalScanMatcherHistogram { get; set; }
|
||||
|
||||
[JsonPropertyName("local_pose")]
|
||||
public Rigid3dProto LocalPose { get; set; }
|
||||
|
||||
public TrajectoryNodeData(
|
||||
long timestamp,
|
||||
Quaterniond gravityAlignment,
|
||||
Rigid3dProto localPose,
|
||||
CompressedPointCloud? filteredGravityAlignedPointCloud = null,
|
||||
CompressedPointCloud? highResolutionPointCloud = null,
|
||||
CompressedPointCloud? lowResolutionPointCloud = null,
|
||||
List<double>? rotationalScanMatcherHistogram = null)
|
||||
{
|
||||
Timestamp = timestamp;
|
||||
GravityAlignment = gravityAlignment;
|
||||
LocalPose = localPose;
|
||||
FilteredGravityAlignedPointCloud = filteredGravityAlignedPointCloud;
|
||||
HighResolutionPointCloud = highResolutionPointCloud;
|
||||
LowResolutionPointCloud = lowResolutionPointCloud;
|
||||
RotationalScanMatcherHistogram = rotationalScanMatcherHistogram;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Sensor;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of adaptive voxel filter options.
|
||||
/// </summary>
|
||||
public struct AdaptiveVoxelFilterOptions(double maxLength, double minNumPoints, double maxRange)
|
||||
{
|
||||
/// <summary>
|
||||
/// Maximum length of a voxel edge.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_length")]
|
||||
public double MaxLength { get; set; } = maxLength;
|
||||
|
||||
/// <summary>
|
||||
/// If there are more points and not at least 'min_num_points' remain, the
|
||||
/// voxel length is reduced trying to get this minimum number of points.
|
||||
/// </summary>
|
||||
[JsonPropertyName("min_num_points")]
|
||||
public double MinNumPoints { get; set; } = minNumPoints;
|
||||
|
||||
/// <summary>
|
||||
/// Points further away from the origin are removed.
|
||||
/// </summary>
|
||||
[JsonPropertyName("max_range")]
|
||||
public double MaxRange { get; set; } = maxRange;
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using CartographerSharp.Models.Transform;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Sensor;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a rangefinder point.
|
||||
/// </summary>
|
||||
public struct RangefinderPoint(Vector3f position)
|
||||
{
|
||||
[JsonPropertyName("position")]
|
||||
public Vector3f Position { get; set; } = position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a timed rangefinder point.
|
||||
/// </summary>
|
||||
public struct TimedRangefinderPoint(Vector3f position, double time)
|
||||
{
|
||||
[JsonPropertyName("position")]
|
||||
public Vector3f Position { get; set; } = position;
|
||||
|
||||
[JsonPropertyName("time")]
|
||||
public double Time { get; set; } = time;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compressed collection of a 3D point cloud.
|
||||
/// </summary>
|
||||
public struct CompressedPointCloud(int numPoints, List<int> pointData)
|
||||
{
|
||||
[JsonPropertyName("num_points")]
|
||||
public int NumPoints { get; set; } = numPoints;
|
||||
|
||||
[JsonPropertyName("point_data")]
|
||||
public List<int> PointData { get; set; } = pointData ?? [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proto representation of ::cartographer::sensor::TimedPointCloudData.
|
||||
/// </summary>
|
||||
public struct TimedPointCloudData(
|
||||
long timestamp,
|
||||
Vector3f origin,
|
||||
List<Vector4f>? pointDataLegacy = null,
|
||||
List<TimedRangefinderPoint>? pointData = null,
|
||||
List<double>? intensities = null)
|
||||
{
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; } = timestamp;
|
||||
|
||||
[JsonPropertyName("origin")]
|
||||
public Vector3f Origin { get; set; } = origin;
|
||||
|
||||
[JsonPropertyName("point_data_legacy")]
|
||||
public List<Vector4f> PointDataLegacy { get; set; } = pointDataLegacy ?? [];
|
||||
|
||||
[JsonPropertyName("point_data")]
|
||||
public List<TimedRangefinderPoint> PointData { get; set; } = pointData ?? [];
|
||||
|
||||
[JsonPropertyName("intensities")]
|
||||
public List<double> Intensities { get; set; } = intensities ?? [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proto representation of ::cartographer::sensor::RangeData.
|
||||
/// </summary>
|
||||
public struct RangeData(
|
||||
Vector3f origin,
|
||||
List<Vector3f>? returnsLegacy = null,
|
||||
List<Vector3f>? missesLegacy = null,
|
||||
List<RangefinderPoint>? returns = null,
|
||||
List<RangefinderPoint>? misses = null)
|
||||
{
|
||||
[JsonPropertyName("origin")]
|
||||
public Vector3f Origin { get; set; } = origin;
|
||||
|
||||
[JsonPropertyName("returns_legacy")]
|
||||
public List<Vector3f> ReturnsLegacy { get; set; } = returnsLegacy ?? [];
|
||||
|
||||
[JsonPropertyName("misses_legacy")]
|
||||
public List<Vector3f> MissesLegacy { get; set; } = missesLegacy ?? [];
|
||||
|
||||
[JsonPropertyName("returns")]
|
||||
public List<RangefinderPoint> Returns { get; set; } = returns ?? [];
|
||||
|
||||
[JsonPropertyName("misses")]
|
||||
public List<RangefinderPoint> Misses { get; set; } = misses ?? [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proto representation of ::cartographer::sensor::ImuData.
|
||||
/// </summary>
|
||||
public struct ImuData(long timestamp, Vector3d linearAcceleration, Vector3d angularVelocity)
|
||||
{
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; } = timestamp;
|
||||
|
||||
[JsonPropertyName("linear_acceleration")]
|
||||
public Vector3d LinearAcceleration { get; set; } = linearAcceleration;
|
||||
|
||||
[JsonPropertyName("angular_velocity")]
|
||||
public Vector3d AngularVelocity { get; set; } = angularVelocity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proto representation of ::cartographer::sensor::OdometryData.
|
||||
/// </summary>
|
||||
public struct OdometryData(long timestamp, Rigid3dProto pose)
|
||||
{
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; } = timestamp;
|
||||
|
||||
[JsonPropertyName("pose")]
|
||||
public Rigid3dProto Pose { get; set; } = pose;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proto representation of ::cartographer::sensor::FixedFramePoseData.
|
||||
/// </summary>
|
||||
public struct FixedFramePoseData(long timestamp, Rigid3dProto pose)
|
||||
{
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; } = timestamp;
|
||||
|
||||
[JsonPropertyName("pose")]
|
||||
public Rigid3dProto Pose { get; set; } = pose;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proto representation of ::cartographer::sensor::LandmarkData.
|
||||
/// </summary>
|
||||
public struct LandmarkData(long timestamp, List<LandmarkData.LandmarkObservation>? landmarkObservations = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// Landmark observation within LandmarkData.
|
||||
/// </summary>
|
||||
public struct LandmarkObservation(
|
||||
byte[] id,
|
||||
Rigid3dProto landmarkToTrackingTransform,
|
||||
double translationWeight,
|
||||
double rotationWeight)
|
||||
{
|
||||
[JsonPropertyName("id")]
|
||||
public byte[] Id { get; set; } = id ?? [];
|
||||
|
||||
[JsonPropertyName("landmark_to_tracking_transform")]
|
||||
public Rigid3dProto LandmarkToTrackingTransform { get; set; } = landmarkToTrackingTransform;
|
||||
|
||||
[JsonPropertyName("translation_weight")]
|
||||
public double TranslationWeight { get; set; } = translationWeight;
|
||||
|
||||
[JsonPropertyName("rotation_weight")]
|
||||
public double RotationWeight { get; set; } = rotationWeight;
|
||||
}
|
||||
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; } = timestamp;
|
||||
|
||||
[JsonPropertyName("landmark_observations")]
|
||||
public List<LandmarkObservation> LandmarkObservations { get; set; } = landmarkObservations ?? [];
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2018 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using CartographerSharp.Common.Time;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Transform;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a timestamped 3D transformation.
|
||||
/// </summary>
|
||||
public struct TimestampedTransform(long time, Rigid3dProto transform)
|
||||
{
|
||||
/// <summary>
|
||||
/// Time in Universal Time Scale ticks (100 nanosecond ticks since epoch).
|
||||
/// </summary>
|
||||
[JsonPropertyName("time")]
|
||||
public long Time { get; set; } = time;
|
||||
|
||||
/// <summary>
|
||||
/// The 3D transformation.
|
||||
/// </summary>
|
||||
[JsonPropertyName("transform")]
|
||||
public Rigid3dProto Transform { get; set; } = transform;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a TimestampedTransform from a DateTime and Rigid3d.
|
||||
/// </summary>
|
||||
public static TimestampedTransform FromDateTime(DateTime time, CartographerSharp.Transform.Rigid3d transform)
|
||||
{
|
||||
return new TimestampedTransform(
|
||||
TimeUtils.ToUniversal(time),
|
||||
transform
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the time to a DateTime.
|
||||
/// </summary>
|
||||
public readonly DateTime ToDateTime()
|
||||
{
|
||||
return TimeUtils.FromUniversal(Time);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2016 The Cartographer Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using CartographerSharp.Transform;
|
||||
using RobotNet10.Shared.Numbers;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CartographerSharp.Models.Transform;
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a 2D vector (double precision).
|
||||
/// </summary>
|
||||
public struct Vector2d(double x, double y)
|
||||
{
|
||||
[JsonPropertyName("x")]
|
||||
public double X { get; set; } = x;
|
||||
|
||||
[JsonPropertyName("y")]
|
||||
public double Y { get; set; } = y;
|
||||
|
||||
public static implicit operator Vector2(Vector2d v) => new(v.X, v.Y);
|
||||
public static implicit operator Vector2d(Vector2 v) => new(v.X, v.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a 2D vector (single precision).
|
||||
/// </summary>
|
||||
public struct Vector2f(double x, double y)
|
||||
{
|
||||
[JsonPropertyName("x")]
|
||||
public double X { get; set; } = x;
|
||||
|
||||
[JsonPropertyName("y")]
|
||||
public double Y { get; set; } = y;
|
||||
|
||||
public static implicit operator Vector2(Vector2f v) => new(v.X, v.Y);
|
||||
public static implicit operator Vector2f(Vector2 v) => new(v.X, v.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a 3D vector (double precision).
|
||||
/// </summary>
|
||||
public struct Vector3d(double x, double y, double z)
|
||||
{
|
||||
[JsonPropertyName("x")]
|
||||
public double X { get; set; } = x;
|
||||
|
||||
[JsonPropertyName("y")]
|
||||
public double Y { get; set; } = y;
|
||||
|
||||
[JsonPropertyName("z")]
|
||||
public double Z { get; set; } = z;
|
||||
|
||||
public static implicit operator Vector3(Vector3d v) => new(v.X, v.Y, v.Z);
|
||||
public static implicit operator Vector3d(Vector3 v) => new(v.X, v.Y, v.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a 3D vector (single precision).
|
||||
/// </summary>
|
||||
public struct Vector3f(double x, double y, double z)
|
||||
{
|
||||
[JsonPropertyName("x")]
|
||||
public double X { get; set; } = x;
|
||||
|
||||
[JsonPropertyName("y")]
|
||||
public double Y { get; set; } = y;
|
||||
|
||||
[JsonPropertyName("z")]
|
||||
public double Z { get; set; } = z;
|
||||
|
||||
public static implicit operator Vector3(Vector3f v) => new(v.X, v.Y, v.Z);
|
||||
public static implicit operator Vector3f(Vector3 v) => new(v.X, v.Y, v.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a 4D vector (single precision).
|
||||
/// </summary>
|
||||
public struct Vector4f(double x, double y, double z, double t)
|
||||
{
|
||||
[JsonPropertyName("x")]
|
||||
public double X { get; set; } = x;
|
||||
|
||||
[JsonPropertyName("y")]
|
||||
public double Y { get; set; } = y;
|
||||
|
||||
[JsonPropertyName("z")]
|
||||
public double Z { get; set; } = z;
|
||||
|
||||
[JsonPropertyName("t")]
|
||||
public double T { get; set; } = t;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a quaternion (double precision).
|
||||
/// </summary>
|
||||
public struct Quaterniond(double x, double y, double z, double w)
|
||||
{
|
||||
[JsonPropertyName("x")]
|
||||
public double X { get; set; } = x;
|
||||
|
||||
[JsonPropertyName("y")]
|
||||
public double Y { get; set; } = y;
|
||||
|
||||
[JsonPropertyName("z")]
|
||||
public double Z { get; set; } = z;
|
||||
|
||||
[JsonPropertyName("w")]
|
||||
public double W { get; set; } = w;
|
||||
|
||||
public static implicit operator Quaternion(Quaterniond q) => new(q.X, q.Y, q.Z, q.W);
|
||||
public static implicit operator Quaterniond(Quaternion q) => new(q.X, q.Y, q.Z, q.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a quaternion (single precision).
|
||||
/// </summary>
|
||||
public struct Quaternionf(double x, double y, double z, double w)
|
||||
{
|
||||
[JsonPropertyName("x")]
|
||||
public double X { get; set; } = x;
|
||||
|
||||
[JsonPropertyName("y")]
|
||||
public double Y { get; set; } = y;
|
||||
|
||||
[JsonPropertyName("z")]
|
||||
public double Z { get; set; } = z;
|
||||
|
||||
[JsonPropertyName("w")]
|
||||
public double W { get; set; } = w;
|
||||
|
||||
public static implicit operator Quaternion(Quaternionf q) => new(q.X, q.Y, q.Z, q.W);
|
||||
public static implicit operator Quaternionf(Quaternion q) => new(q.X, q.Y, q.Z, q.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a rigid 2D transformation (double precision).
|
||||
/// </summary>
|
||||
public struct Rigid2dProto(Vector2d translation, double rotation)
|
||||
{
|
||||
[JsonPropertyName("translation")]
|
||||
public Vector2d Translation { get; set; } = translation;
|
||||
|
||||
[JsonPropertyName("rotation")]
|
||||
public double Rotation { get; set; } = rotation;
|
||||
|
||||
public static implicit operator Rigid2d(Rigid2dProto proto)
|
||||
{
|
||||
return new Rigid2d(proto.Translation, proto.Rotation);
|
||||
}
|
||||
|
||||
public static implicit operator Rigid2dProto(Rigid2d rigid)
|
||||
{
|
||||
return new Rigid2dProto(rigid.Translation, rigid.Rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a rigid 2D transformation (single precision).
|
||||
/// </summary>
|
||||
public struct Rigid2fProto(Vector2f translation, double rotation)
|
||||
{
|
||||
[JsonPropertyName("translation")]
|
||||
public Vector2f Translation { get; set; } = translation;
|
||||
|
||||
[JsonPropertyName("rotation")]
|
||||
public double Rotation { get; set; } = rotation;
|
||||
|
||||
public static implicit operator Rigid2f(Rigid2fProto proto)
|
||||
{
|
||||
return new Rigid2f(proto.Translation, proto.Rotation);
|
||||
}
|
||||
|
||||
public static implicit operator Rigid2fProto(Rigid2f rigid)
|
||||
{
|
||||
return new Rigid2fProto(rigid.Translation, rigid.Rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a rigid 3D transformation (double precision).
|
||||
/// </summary>
|
||||
public struct Rigid3dProto(Vector3d translation, Quaterniond rotation)
|
||||
{
|
||||
[JsonPropertyName("translation")]
|
||||
public Vector3d Translation { get; set; } = translation;
|
||||
|
||||
[JsonPropertyName("rotation")]
|
||||
public Quaterniond Rotation { get; set; } = rotation;
|
||||
|
||||
public static implicit operator Rigid3d(Rigid3dProto proto)
|
||||
{
|
||||
return new Rigid3d(proto.Translation, proto.Rotation);
|
||||
}
|
||||
|
||||
public static implicit operator Rigid3dProto(Rigid3d rigid)
|
||||
{
|
||||
return new Rigid3dProto(rigid.Translation, rigid.Rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protocol buffer representation of a rigid 3D transformation (single precision).
|
||||
/// </summary>
|
||||
public struct Rigid3fProto(Vector3f translation, Quaternionf rotation)
|
||||
{
|
||||
[JsonPropertyName("translation")]
|
||||
public Vector3f Translation { get; set; } = translation;
|
||||
|
||||
[JsonPropertyName("rotation")]
|
||||
public Quaternionf Rotation { get; set; } = rotation;
|
||||
|
||||
public static implicit operator Rigid3f(Rigid3fProto proto)
|
||||
{
|
||||
return new Rigid3f(proto.Translation, proto.Rotation);
|
||||
}
|
||||
|
||||
public static implicit operator Rigid3fProto(Rigid3f rigid)
|
||||
{
|
||||
return new Rigid3fProto(rigid.Translation, rigid.Rotation);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user