diff options
Diffstat (limited to 'ink_stroke_modeler/params.cc')
-rw-r--r-- | ink_stroke_modeler/params.cc | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/ink_stroke_modeler/params.cc b/ink_stroke_modeler/params.cc new file mode 100644 index 0000000..99542e1 --- /dev/null +++ b/ink_stroke_modeler/params.cc @@ -0,0 +1,157 @@ +// Copyright 2022 Google LLC +// +// 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. + +#include "ink_stroke_modeler/params.h" + +#include <cmath> + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "absl/strings/substitute.h" +#include "absl/types/variant.h" +#include "ink_stroke_modeler/internal/validation.h" + +// This convenience macro evaluates the given expression, and if it does not +// return an OK status, returns and propagates the status. +#define RETURN_IF_ERROR(expr) \ + do { \ + if (auto status = (expr); !status.ok()) return status; \ + } while (false) + +namespace ink { +namespace stroke_model { + +absl::Status ValidatePositionModelerParams( + const PositionModelerParams& params) { + RETURN_IF_ERROR(ValidateGreaterThanZero(params.spring_mass_constant, + "PredictionParams::spring_mass")); + return ValidateGreaterThanZero(params.drag_constant, + "PredictionParams::drag_ratio"); +} + +absl::Status ValidateSamplingParams(const SamplingParams& params) { + RETURN_IF_ERROR(ValidateGreaterThanZero(params.min_output_rate, + "PredictionParams::min_output_rate")); + RETURN_IF_ERROR(ValidateGreaterThanZero( + params.end_of_stroke_stopping_distance, + "PredictionParams::end_of_stroke_stopping_distance")); + return ValidateGreaterThanZero( + params.end_of_stroke_max_iterations, + "PredictionParams::end_of_stroke_stopping_distance"); +} + +absl::Status ValidateStylusStateModelerParams( + const StylusStateModelerParams& params) { + return ValidateGreaterThanZero(params.max_input_samples, + "StylusStateModelerParams::max_input_samples"); +} + +absl::Status ValidateWobbleSmootherParams(const WobbleSmootherParams& params) { + RETURN_IF_ERROR(ValidateGreaterThanOrEqualToZero( + params.timeout.Value(), "WobbleSmootherParams::timeout")); + RETURN_IF_ERROR(ValidateGreaterThanOrEqualToZero( + params.speed_floor, "WobbleSmootherParams::speed_floor")); + RETURN_IF_ERROR(ValidateIsFiniteNumber( + params.speed_ceiling, "WobbleSmootherParams::speed_ceiling")); + if (params.speed_ceiling < params.speed_floor) { + return absl::InvalidArgumentError(absl::Substitute( + "WobbleSmootherParams::speed_ceiling must be greater than or " + "equal to WobbleSmootherParams::speed_floor ($0). Actual " + "value: $1", + params.speed_floor, params.speed_ceiling)); + } + return absl::OkStatus(); +} + +absl::Status ValidatePredictionParams(const PredictionParams& params) { + if (absl::holds_alternative<StrokeEndPredictorParams>(params)) { + // Nothing to validate. + return absl::OkStatus(); + } + + const KalmanPredictorParams& kalman_params = + absl::get<KalmanPredictorParams>(params); + RETURN_IF_ERROR(ValidateGreaterThanZero( + kalman_params.process_noise, "KalmanPredictorParams::process_noise")); + RETURN_IF_ERROR( + ValidateGreaterThanZero(kalman_params.measurement_noise, + "KalmanPredictorParams::measurement_noise")); + RETURN_IF_ERROR( + ValidateGreaterThanZero(kalman_params.min_stable_iteration, + "KalmanPredictorParams::min_stable_iteration")); + RETURN_IF_ERROR( + ValidateGreaterThanZero(kalman_params.max_time_samples, + "KalmanPredictorParams::max_time_samples")); + RETURN_IF_ERROR( + ValidateGreaterThanZero(kalman_params.min_catchup_velocity, + "KalmanPredictorParams::min_catchup_velocity")); + RETURN_IF_ERROR( + ValidateIsFiniteNumber(kalman_params.acceleration_weight, + "KalmanPredictorParams::acceleration_weight")); + RETURN_IF_ERROR(ValidateIsFiniteNumber(kalman_params.jerk_weight, + "KalmanPredictorParams::jerk_weight")); + RETURN_IF_ERROR( + ValidateGreaterThanZero(kalman_params.prediction_interval.Value(), + "KalmanPredictorParams::jerk_weight")); + + const KalmanPredictorParams::ConfidenceParams& confidence_params = + kalman_params.confidence_params; + RETURN_IF_ERROR(ValidateGreaterThanZero( + confidence_params.desired_number_of_samples, + "KalmanPredictorParams::ConfidenceParams::desired_number_of_samples")); + RETURN_IF_ERROR(ValidateGreaterThanZero( + confidence_params.max_estimation_distance, + "KalmanPredictorParams::ConfidenceParams::max_estimation_distance")); + RETURN_IF_ERROR(ValidateGreaterThanOrEqualToZero( + confidence_params.min_travel_speed, + "KalmanPredictorParams::ConfidenceParams::min_travel_speed")); + RETURN_IF_ERROR(ValidateIsFiniteNumber( + confidence_params.max_travel_speed, + "KalmanPredictorParams::ConfidenceParams::max_travel_speed")); + if (confidence_params.max_travel_speed < confidence_params.min_travel_speed) { + return absl::InvalidArgumentError( + absl::Substitute("KalmanPredictorParams::ConfidenceParams::max_" + "travel_speed must be greater than or equal to " + "KalmanPredictorParams::ConfidenceParams::min_" + "travel_speed ($0). Actual value: $1", + confidence_params.min_travel_speed, + confidence_params.max_travel_speed)); + } + RETURN_IF_ERROR(ValidateGreaterThanZero( + confidence_params.max_linear_deviation, + "KalmanPredictorParams::ConfidenceParams::max_linear_deviation")); + if (confidence_params.baseline_linearity_confidence < 0 || + confidence_params.baseline_linearity_confidence > 1) { + return absl::InvalidArgumentError(absl::Substitute( + "KalmanPredictorParams::ConfidenceParams::baseline_linearity_" + "confidence must lie in the interval [0, 1]. Actual value: $0", + confidence_params.baseline_linearity_confidence)); + } + return absl::OkStatus(); +} + +absl::Status ValidateStrokeModelParams(const StrokeModelParams& params) { + RETURN_IF_ERROR(ValidateWobbleSmootherParams(params.wobble_smoother_params)); + RETURN_IF_ERROR( + ValidatePositionModelerParams(params.position_modeler_params)); + RETURN_IF_ERROR(ValidateSamplingParams(params.sampling_params)); + RETURN_IF_ERROR( + ValidateStylusStateModelerParams(params.stylus_state_modeler_params)); + return ValidatePredictionParams(params.prediction_params); +} + +} // namespace stroke_model +} // namespace ink + +#undef RETURN_IF_ERROR |