Skip to content

Commit

Permalink
Change GetInvalidityReport() to CreateInvalidityReport() and change r…
Browse files Browse the repository at this point in the history
…eturn type to use std::optional.
  • Loading branch information
Paul Mitiguy committed Dec 20, 2024
1 parent bbb21ae commit 6fcffe6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
10 changes: 6 additions & 4 deletions multibody/tree/rotational_inertia.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ boolean<T> RotationalInertia<
}

template <typename T>
std::string RotationalInertia<T>::GetInvalidityReport() const {
std::optional<std::string> RotationalInertia<T>::CreateInvalidityReport()
const {
// Default return value is an empty string (this RotationalInertia is valid).
std::string error_message;
if (IsNaN()) {
Expand All @@ -235,19 +236,20 @@ std::string RotationalInertia<T>::GetInvalidityReport() const {
}
}
}
if (error_message.empty()) return std::nullopt;
return error_message;
}

template <typename T>
void RotationalInertia<T>::ThrowIfNotPhysicallyValidImpl(
const char* func_name) const {
DRAKE_DEMAND(func_name != nullptr);
const std::string reason_for_invalidity = GetInvalidityReport();
if (!reason_for_invalidity.empty()) {
const std::optional<std::string> invalidity_report = CreateInvalidityReport();
if (invalidity_report.has_value()) {
const std::string error_message = fmt::format(
"{}(): The rotational inertia\n"
"{}did not pass the test CouldBePhysicallyValid().{}",
func_name, *this, reason_for_invalidity);
func_name, *this, *invalidity_report);
throw std::logic_error(error_message);
}
}
Expand Down
19 changes: 10 additions & 9 deletions multibody/tree/rotational_inertia.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <cmath>
#include <limits>
#include <memory>
#include <optional>
#include <ostream>
#include <sstream>
#include <string>
Expand Down Expand Up @@ -605,7 +606,7 @@ class RotationalInertia {
/// calculated (eigenvalue solver) or if scalar type T cannot be
/// converted to a double.
boolean<T> CouldBePhysicallyValid() const {
return boolean<T>(GetInvalidityReport().empty());
return boolean<T>(!CreateInvalidityReport().has_value());
}

/// Re-expresses `this` rotational inertia `I_BP_E` in place to `I_BP_A`.
Expand Down Expand Up @@ -977,15 +978,15 @@ class RotationalInertia {
return Ixx + epsilon >= 0 && Iyy + epsilon >= 0 && Izz + epsilon >= 0;
}

// Returns an error string if `this` RotationalInertia is verifiably invalid
// or else returns an empty string (an empty string does not _guarantee_
// validity). For numerical type T, validity includes tests that principal
// moments of inertia (eigenvalues) are positive and satisfy the triangle
// inequality. For symbolic type T, tests are rudimentary (e.g., test for NaN
// moments or products of inertia).
std::string GetInvalidityReport() const;
// Returns an error string if `this` RotationalInertia is verifiably invalid.
// Note: Not returning an error string does not _guarantee_ validity.
// For numerical type T, validity includes tests that principal moments of
// inertia (eigenvalues) are positive and satisfy the triangle inequality.
// For symbolic type T, tests are rudimentary (e.g., test for NaN moments or
// products of inertia.
std::optional<std::string> CreateInvalidityReport() const;

// Throw an exception if GetInvalidityReport() returns an error string.
// Throw an exception if CreateInvalidityReport() returns an error string.
void ThrowIfNotPhysicallyValidImpl(const char* func_name) const;

// ==========================================================================
Expand Down

0 comments on commit 6fcffe6

Please sign in to comment.