|
FhSim
3.1.0
Marine systems simulation
|
Dated 2026-09-24, state of the checked-out commit da8e80f (branch main, clean).
Update, same day: the repository now has a tests/ directory with one GTest target, test_fhsim_coribo. It is registered with CTest when FH_WITH_TESTS is on, and it checks the constraint solver's hand-derived Jacobians against finite differences (CORIBO-0002, resolved). The check found a sign error, filed as 0006 — Point-versus-disk face contact: the disk's rotational Jacobian has the wrong sign. WinchableCable still has no behavioural test (0001 — WinchableCable has no automated behavioural test of any kind), because the shipped example does not start (0004 — The shipped CoriboCable.xml example stops before the first step: cableStates initial conditions are incomplete). The rest of this report describes the state at da8e80f.
fhsim_coribo has no automated test suite. The top-level CMakeLists.txt declares FH_WITH_TESTS (default OFF, CMakeLists.txt:13) and, when it is on, finds GTest and calls enable_testing() (CMakeLists.txt:27-29), but the line that would add a test directory is commented out and no such directory exists:
(CMakeLists.txt:47-50). There is no ctest target to run and no _ref.csv/_Test.cpp tree of any kind (openwiki/testing.md documents the same conclusion). README.md:127-131 describes an integration-test workflow (set SFH_LICENSE_FILE, pass -c tools.build:skip_test=False to conan install) that assumes a test_fhsim_coribo* executable appears in the playpen build tree; since no test target is configured, that workflow currently has nothing to run.
The only thing that executes at all is the Conan compile-and-link smoke check, test_package/test_package.cpp, run as part of conan create. It does three things and no more (test_package/test_package.cpp:13-68):
GeometryTools::Points and calls Distance() on them, proving the installed headers compile and the library links.getSimObject symbol.getSimObject("WinchableCable", "winch", &creator) inside a try block whose catch (Exceptions&) logs *"Successfully able to call constructor"* — so a thrown exception from the constructor is logged as success, not failure. The function returns 0 unconditionally; the successfulness variable it assigns is never read (test_package/test_package.cpp:44, :68). No port value, constraint force, or integrator step is checked anywhere.**Jacobian checking (fhsim::test::JacobianChecker/TestSpec.jacobianMode) does not apply here at all**, for two independent reasons: RunTest/TestSpec are never invoked anywhere in this repository (there is no scenario for the mechanism to run against), and WinchableCable itself overrides none of HasJacobians()/OdeJacobian()/ HasPortJacobians(), so even a hypothetical RunTest scenario over it would run with the engine's finite-difference fallback and no analytic Jacobian for CheckJacobians to compare against. This is a different, and more complete, gap than in fhsim_environment: there the mechanism is wired up and unused; here there is no harness for it to be wired into.
A different kind of analytic derivative does exist in this library, one step down from the SimObject level: fhsim_coribo's internal constraint solver computes hand-derived Jacobians of its own (see below). They are outside the FhSim SimObject Jacobian API and are not reached by anything described above.
One row per registration in src/fhsim_coribo.cpp (ADD_SIMOBJECT_REF, not commented out — there is exactly one):
| SimObject | Input name | Tests | What is asserted | Jacobian implementation | Jacobian verified | Rating | Issues |
|---|---|---|---|---|---|---|---|
WinchableCable | WinchableCable | test_package/test_package.cpp only (compile/link + symbol-resolve + constructor-reachable smoke check) | Nothing behavioural; a thrown constructor exception is logged as success | None at the SimObject level — no HasJacobians/OdeJacobian/HasPortJacobians override (include/fhsim_coribo/WinchableCable.h, src/SimObjects/WinchableCable.cpp); its 15600-state ODE (cableStates) runs on the engine's finite-difference fallback | Not applicable — no RunTest/TestSpec/JacobianChecker invocation exists anywhere in this repository | D | 0001 — WinchableCable has no automated behavioural test of any kind |
Not counted in the table above or in any rating, listed because this is where the library's only real analytic-derivative math lives:
| Component | Role | Tests | Jacobian implementation | Jacobian verified |
|---|---|---|---|---|
Structure classes (LineStructure, RingStructure, SupergridLineStructure, SupergridCable, SupergridWinchCable, Winch) | Reusable building blocks WinchableCable composes; ConstraintSet subclasses plugged into the Newton solve | None | N/A — no independent SimObject-level Jacobian API surface | N/A |
Constraint-solver internals (ConstraintSolver, JointConstraint, GeometryTools, CollisionManager) | Newton-iteration constraint solve behind every WinchableCable step | tests/GeometryTools-Jacobian_Test.cpp, tests/JointConstraint-Jacobian_Test.cpp | Real, hand-derived analytic Jacobians: JointConstraint::QuaternionConstraint_Jacobian (include/fhsim_coribo/JointConstraint.h:183, src/ConstraintSet/JointConstraint.cpp:146-161) and GeometryTools::MinDistanceInfo::JacobianA/JacobianB, hand-derived per geometry pair in every GeometryTools::Distance overload (src/Utilities/GeometryTools.cpp, e.g. the point-point case at :391-401, and again for point/ring, point/disk, point/segment, segment/segment, segment/ring, segment/disk, segment/plane and plane/plane) | Central finite differences for every Distance overload and for QuaternionConstraint_Jacobian. Point-versus-disk face contact fails on the rotation entries (0006 — Point-versus-disk face contact: the disk's rotational Jacobian has the wrong sign) |
Rating legend: A behaviour asserted and the Jacobian verified where one exists; B partly; C smoke/regression only or indirect; D untested.
JointConstraint::QuaternionConstraint_Jacobian** (JointConstraint.cpp:146-161): a closed-form 4x4 derivative of the quaternion constraint w.r.t. the quaternion components, used inside ComputeRigidCoupling and ComputeExternalRigidCoupling (JointConstraint.cpp:332,341,480,485). Complete, and verified against finite differences by tests/JointConstraint-Jacobian_Test.cpp.GeometryTools::MinDistanceInfo::JacobianA/JacobianB**: closed-form derivatives of the minimum-distance scalar between two geometric primitives, hand-derived per pair type (point-point, point-ring, point-disk, point-segment, segment-segment, segment-ring, segment-disk, segment-plane, plane-plane) throughout src/Utilities/GeometryTools.cpp. Verified against finite differences by tests/GeometryTools-Jacobian_Test.cpp. Three families use deliberate approximations and pass with a documented looser tolerance: ring softening (absolute error about 1e-3 on entries of order 1), segment-segment regularisation (about 7e-5), and the interior-point closest-point solve for planes (about 2e-4). The point-versus-disk face branch has the wrong sign on the rotation entries (0006 — Point-versus-disk face contact: the disk's rotational Jacobian has the wrong sign).WinchableCable**: provides no OdeJacobian; its ODE state runs on the engine's finite-difference fallback exclusively. There is no analytic Jacobian at the SimObject level to verify — see 0001 — WinchableCable has no automated behavioural test of any kind.WinchableCable. There is currently no automated behavioural coverage of any kind for the library's only SimObject, and a documented 3.1.0 behavioural change (SetSymplecticStepSize() called again under Euler_i/Heun_i, per CHANGELOG.md) shipped with nothing to catch a mistake in it. See 0001 — WinchableCable has no automated behavioural test of any kind.WinchableCable's Doxygen commentwinch_init_states.dat, as the code and the shipped data file do (CORIBO-0003, resolved).