Version 2.13 Release Notes
Version 2.13.0b0
Added scenarioMovingCamera, demonstrating two message-driven instrument camera platforms on a spacecraft in a circular Earth orbit with fixed prescribed attitude, visible Vizard camera frustums, and offline pose and visualization-wiring tests. This documents the moving-platform alternative for issue 1309 without adding a camera pose-input port.
Added ommHandling to read CCSDS Orbit Mean-Elements Message (OMM) general perturbations data in all four CelesTrak encodings (XML, JSON, CSV and KVN) and convert it to osculating orbital elements, lifting the five-digit catalog number limit of the TLE format. Includes scenarioOrbitFromOmm, a tutorial with bundled synthetic OMM data, spacecraft initialization, and orbit, altitude and speed figures.
Added scenarioThrusterArm, scenarioRoboticGrappling, and scenarioAerobrake, which demonstrate effector branching across the supported parent and child effector pairings.
Added scenarioBranchingVerification, which verifies the branched equations of motion against the integrator’s formal order and the impulse-momentum theorems.
Fixed C++ Module: constraintDynamicEffector applying its constraint force and torque while the device status message commanded it off, which previously suppressed only the output message.
Added Accuracy Comparison with GMAT and Orekit, a rough comparison of Basilisk orbit propagation against GMAT and Orekit for zonal and tesseral gravity up to degree and order 70, Sun and Moon third-body forces, solar radiation pressure, and exponential-atmosphere drag, in LEO, sun-synchronous, Molniya, GTO, and GEO orbits at several epochs, all in the ICRF axes. The exponential-atmosphere drag is compared with both tools, and the faceted drag and solar radiation pressure of a box spacecraft with a fixed and with a spinning attitude are compared with Orekit. The scripts that generate the GMAT and Orekit reference ephemerides, which also write a manifest with the case configuration, frame, tool versions and data checksums that is validated before the comparison, and that run the comparison, which also compare the altitude and density of the three exponential atmospheres at a set of probe points before any propagation, are in
benchmarks/accuracyComparison, and the page explains how to reproduce the results.Fixed the gravity effector extrapolating the planet orientation with a first-order update of the matrix elements, which is not orthonormal. The orientation is now advanced as a rotation about the planet angular velocity. Before, a SPICE-driven planet distorted even a point-mass field by a relative error of order \((\omega\,\Delta t)^2\) of the time since the planet message was written. The
J20002PfixandJ20002Pfix_dotstate properties of the gravity bodies were also stored transposed after each gravity evaluation, as \([NP]\) instead of the documented \([PN]\). They now hold \([PN]\) and \([\dot{PN}]\) as documented, which matters to code that reads these properties.Added
setExtrapolateScStateToStepMidpoint()andgetExtrapolateScStateToStepMidpoint()to C++ Module: atmosphereBase (including C++ Module: msisAtmosphere, C++ Module: exponentialAtmosphere, and C++ Module: tabularAtmosphere), C++ Module: windBase, C++ Module: magneticFieldBase, C++ Module: eclipse, and C++ Module: solarFlux. These modules evaluate the spacecraft state of the previous step because they run before the spacecraft. When the extrapolation is enabled, the spacecraft position is advanced to the middle of the interval the next spacecraft update integrates. This removes a step-size dependent error. The planet (or sun) position and orientation are moved to the same epoch, so a translating planet does not bias the relative position. Stale messages are not extrapolated. The extrapolation is disabled by default and requires that the module is updated with the same task period as the spacecraft. The extrapolation starts once two spacecraft write times show an interval equal to the module update interval, so the first updates are not extrapolated, and during them the planet is moved back to the epoch of the spacecraft state to keep the relative geometry consistent. If the spacecraft is faster or slower than the module, nothing is extrapolated, and a warning is logged when a spacecraft message is found not to have been written at the previous module update. A mismatch is not always detectable, since a message written at the current module update is used as written, but a message that is not the output of the previous module update is never extrapolated. With several spacecraft the extrapolation is applied to all of them and to the planets, or to none.Added
setPlanetPolarRadius()andgetPlanetPolarRadius()to C++ Module: atmosphereBase to compute the altitude, and the latitude in C++ Module: msisAtmosphere, above an oblate ellipsoid. The default remains a sphere.Added
setUseApparentSolarTime()andgetUseApparentSolarTime()to C++ Module: msisAtmosphere to add the equation of time to the local solar time input of NRLMSISE-00. The default remains the mean solar time.Added
setUseApHistory()andgetUseApHistory()to C++ Module: msisAtmosphere to make NRLMSISE-00 use the 3-hour Ap history of the space weather messages (switch 9 set to -1) instead of the daily Ap, which follows a geomagnetic storm more closely. The default remains the daily Ap.Fixed
PCPF2LLA()returning an altitude that was wrong for a position exactly at a pole of an oblate planet, where the equatorial component is zero.Fixed C++ Module: msisAtmosphere, C++ Module: windBase, C++ Module: magneticFieldBase, and C++ Module: magneticFieldWMM converting the UTC epoch with
mktime, which uses the time zone of the computer. On a computer in a time zone with daylight saving time, the local solar time of C++ Module: msisAtmosphere was one hour wrong after a simulation crossed a daylight saving transition. The epoch is now converted as UTC with the newarchitecture/utilities/utcTime.h.Changed C++ Module: facetSRPDynamicEffector to use the solar flux
SOLAR_FLUX_EARTHof 1361 W/m2 at 1 AU, as C++ Module: radiationPressure does, instead of 1368 W/m2. The facet SRP force is 0.5% smaller than before.Normalized
GaussMarkovsecondary seeds to 32 bits so the same base seed produces identical raw engine sequences across standard libraries. This changes existing secondary sensor sequences on builds with a 64-bitstd::minstd_rand::result_type(such as typical Linux/libstdc++ builds). Sensor noise samples and fault events are still not guaranteed to match across standard libraries becausestd::normal_distributionandstd::uniform_real_distributionuse implementation-defined algorithms.Added prescribed rotation and translation solar array deployment sequence scenarioRotTransArrayDeployment to examples, with unequal deployment rates and heavier panel elements to show the spacecraft hub’s response.
Fixed
GaussMarkov::deriveSecondarySeed()collisions for 64-bit input seeds by checking both 32-bit and 64-bit primary engine states while preserving existing primary seeding.Fixed
BSpline.approximate()ignoring final-acceleration components because of incorrect constraint-vector indexing (GitHub issue 1563).Added scenarioHingedRigidBodyMuJoCo to demonstrate hinged solar-panel dynamics and an orbital burn using MuJoCo.
Added scenarioFlexiblePanelMuJoCo to demonstrate attitude control with a flexible, multi-segment solar panel using MuJoCo.
Added scenarioMomentumDumpingMuJoCo to demonstrate reaction-wheel momentum dumping with thrusters using MuJoCo.
Added Python Module: cmdTorqueBodyToTorqueAtSite, a Python module that converts a
CmdTorqueBodyMsginto aTorqueAtSiteMsgwith an optional constant body-to-site rotation.GitHub issue 1573: Rust
MsgReaderports now exposeis_written,time_written(nanoseconds), andmodule_idfor the subscribed source message.Fixed out-of-bounds table reads in the C
debyeLength()utility for altitudes from 2,000 km through 30,000 km (GitHub issue 1581).Fixed out-of-bounds table reads for NaN altitude inputs to the C
debyeLength()utility; these inputs now produce an error diagnostic and return NaN.Fixed the
vscmgcase inbenchmarks/dynamics/benchmark_state_effectors.pydefining two of its four VSCMG gimbal frames with a left-handedgsHat0_B/gtHat0_B/ggHat_Baxis set, which madeInitializeSimulation()raise aBSK_ERROR.Fixed C++ Module: groundLocation, C++ Module: stripLocation and C++ Module: groundMapping crossing the planet angular velocity, which was expressed in planet-fixed components, with inertial vectors. This affected
v_BL_L,range_dot,az_dotandel_dotof the access messages when the planet spin axis was not aligned with the inertial 3-axis.Fixed C++ Module: groundLocation and C++ Module: groundMapping ignoring the planet translational velocity from
planetInMsgwhen computingv_BL_L,range_dot,az_dotandel_dotof the access messages.Fixed C++ Module: groundMapping using an uninitialized planet-fixed to SEZ rotation matrix; it is now computed for each mapping point from its latitude and longitude.
Fixed C++ Module: stripLocation not populating the
v_BL_Lfield of its access messages.Fixed C++ Module: stripLocation omitting the rotation of the moving target’s local SEZ frame from
v_BL_L,az_dotandel_dot; these outputs now agree with derivatives of the published geometry while the target moves along the strip.Fixed C++ Module: stripLocation retaining its acquisition velocity after reaching the endpoint; the target now stops in the planet-fixed frame, keeping its strip state and access rate outputs consistent with the completed trajectory.
Fixed C++ Module: groundMapping not populating the
rHat_LP_Nfield of its ground state messages.Added a guard to C++ Module: groundLocation and C++ Module: groundMapping so that
azimuth,az_dotandel_dotare set to zero, as in C++ Module: stripLocation, instead of being undefined when the horizontal distance to a spacecraft directly overhead of the location vanishes. All three modules account separately for distant-origin position quantization and local frame-transformation round-off, preserving resolvable near-overhead offsets.Updated scenarioThrArmControl to use configuration-driven MuJoCo dynamics and flight software for thruster-arm regulation control.
Added scenarioThrArmTracking to demonstrate spacecraft position and attitude tracking with articulated thruster arms in MuJoCo.
Added the Python Module: arcLineHoldRef guidance module to generate inertial position, velocity, and acceleration references for an arc-to-line-to-hold maneuver.
Fixed keplerianOrbit eccentric and mean anomalies, signed flight-path angles, and rates after construction and
set_a();set_mu()now refreshes derived outputs andoe().rmagreturns the current radius. Anomalies follow theorbitalMotion.f2E()andE2M()conventions without additional angle normalization.Fixed rigid-body kinematics issues #1610 and #1611 across C, Python, Numba, and the corresponding Rust C bindings: conversions and composition preserve identity, small rotations, half-turns, and Euler singularities; PRV rate maps handle zero attitude and angle wrapping handles multiple revolutions. See Numerical scope and representation limits for representation limits.
Preserved Python and Numba list/tuple support and non-contiguous PRV array inputs.
RigidBodyKinematicsNumbanow exposes Python wrappers with Numba overloads instead of public dispatcher objects, avoiding deprecated list reflection; see RigidBodyKinematicsNumba for compiled-call requirements. Added Python/NumbaMRPshadow()and extended the Rust attitude bindings.Fixed C++ Module: spiceInterface GPS week and seconds of
spiceTimeOutMsg, which were computed from TDB instead of atomic time, and its UTC Julian date, which was quantized to 1e-7 day, while preserving the SPICE convention of holding the Julian date at midnight during an inserted leap second.Fixed C++ Module: spiceInterface
GPSSecondsinteger overflow after GPS week 3550, and held the GPS time outputs at zero with a warning when the simulation starts before the GPS epoch.Fixed C++ Module: eclipse returning the occulted instead of the visible fraction of the solar disk during annular eclipses, where the disk of the occulting body lies inside the solar disk.
Fixed the same annular-eclipse formula in
PlanetRadiationBase, used by C++ Module: albedo and C++ Module: earthRadiationModel, to return the visible fraction of the solar disk.Fixed C Module: celestialTwoBodyPoint reference angular acceleration by removing dot products that mixed component frames; added finite-difference regression tests and corrected the documented derivative equations.
Fixed C++ Module: imuSensor
DVFramePlatform, which turned the delta v accumulated since the start of the simulation into a spurious delta v whenever the spacecraft attitude changed between IMU calls. The delta v is now computed fromTotalAccumDV_CN_Nand the change of the sensor velocity relative to the center of mass.Fixed C++ Module: imuSensor
Reset(), which kept the state of the previous IMU call, so the first call after a reset in the middle of a simulation differenced the new state against the state from before the reset. This call now outputs a zero message.Fixed MJSite
stateOutMsgfields that a site does not provide, such as the center of mass states and the accumulated delta v, which were uninitialized and are now zero.Fixed C++ Module: spacecraft
nonConservativeAccelpntB_BandomegaDot_BN_B, which were uninitialized before the first integration step and, withpointMassTranslationalOnly, for the whole simulation.Fixed the GCRS to J2000 frame bias in
tleHandling.frame_bias().Enhanced convergence, accuracy, and numerical robustness in the C and Python orbitalMotion libraries across Kepler solvers, orbital conversions, mean/osculating mapping, and environmental helpers, including singular and degenerate orbit cases (issue 1629).
Preserved existing orbital methods, NumPy scalar outputs, and legacy conventions without deprecation; added optional checked APIs. Element inputs now require inclinations in [0, pi] radians (0 to 180 degrees). See Orbital Motion Compatibility for validation changes and compatibility guidance.
Corrected keplerianOrbit characteristic energy and improved related controller, ephemeris, and C++ Module: eclipse calculations, with expanded regression coverage and updated documentation.
Fixed the spherical harmonics gravity model replacing the reference radius loaded from the coefficient file with
radEquatorof the gravity body when the body was initialized. The radius of the file is now kept; to evaluate the field with a different reference radius, setspherHarm.radEquatorinstead of the bodyradEquator.Spherical harmonics body initialization now requires a finite, positive
GravBodyData.muso orbital gravity and gravity-gradient torque use the same GM. To use the coefficient file GM, setplanet.mu = planet.spherHarm.muBodyafter loading the file and before initializing the simulation.Fixed C++ Module: linkBudget atmospheric slant attenuation by computing each layer’s elevation from the ground ray invariant before accumulating its loss (GitHub issue 1632).
Fixed C++ Module: linkBudget atmospheric layer generation to cover the ground-to-100 km interval with finite exponential spacing and midpoint sampling, eliminating overflow and reducing the sea-level lookup table from 70,979 to 931 cells (GitHub issue 1632).
Split C++ Module: linkBudget atmospheric integration cells at temperature and pressure formula boundaries to reduce absolute attenuation errors near gas absorption lines (GitHub issue 1632).
Added a reproducible fine-grid reference utility and quantitative elevation-clamp regression tests for C++ Module: linkBudget, preserving its existing per-layer sine threshold of 0.0872.
Fixed C++ Module: msisAtmosphere omitting the UT and longitude dependent magnetic activity term of NRLMSISE-00 when
setUseApHistory(True)is used.Fixed the C
ukfLUBckSlv()utility returning a wrong solution when the first nonzero entry of the pivoted right-hand side was below 1 in magnitude.Fixed Conan retry and source-backup configuration to honor
CONAN_HOME, enabling the existing backup server for Linux wheel builds when an upstream source download fails (GitHub issue 1649). TLS and source-checksum verification remain enabled.Release workflows now configure Conan retries and source backups before testing source distributions and can recover previously tested artifacts without moving a release tag (GitHub issue 1649).
Fixed duplicate multi-revolution solutions in the Gooding method of C++ Module: lambertSolver by correcting its initial guesses and safeguarding the minimum-time search against divergence; both solvers now explicitly handle coalesced roots at the minimum transfer time (GitHub issue 1651).
Added explicit prograde/retrograde transfer selection to C++ Module: lambertSolver through
LambertProblemMsgPayload.transferDirectionand to C++ Module: lambertPlanner throughsetTransferDirection; the zero/default value preserves prograde behavior. Polar ties account for floating-point cancellation, and unknown direction integers are rejected before enum conversion (GitHub issue 1652).Fixed macOS Rust debug-stripping failures caused by missing
libLLVM.dylibby installing the selected toolchain’s matching LLVM component in CI and wheel builds, checking stripping even when the compiler reports success, and documenting the local build prerequisite.Added opt-in prograde and retrograde mean-longitude equinoctial averaging to C++ Module: formationBarycenter for circular and equatorial elliptic formations; existing Cartesian and default classical-element results remain unchanged.
Fixed C Module: opNavPoint building
sigma_BRfrom a principal rotation axis in camera frame components. The axis, including the 180 degree fallback axis, is now mapped into body frame components withsigma_CBfromcameraConfigInMsg, so the reference attitude pointsalignAxis_Cat the target for any camera mounting. The module variableeHat180_Bis renamed toeHat180_C, andopNavMnvrVecis now in body frame components.Fixed C Module: opNavPoint discarding the saved heading of an image taken at simulation time 0 on the next update, and ignoring a valid image for one update when it arrived exactly
timeOutseconds after the previous one; with the defaulttimeOutof zero, valid images were never used. A valid image is now always used immediately, and the saved heading is reused untiltimeOutseconds have passed without a valid image. The module variablecurrentHeading_Nis renamed tosavedR_BN_N, as it stores the last measured positionr_BNin inertial frame components rather than a heading.Fixed C Module: opNavPoint retaining valid messages indefinitely and changing their saved inertial heading as the spacecraft rotates. Valid measurements are now consumed once per increasing message write timestamp; retained messages expire normally. Producers must timestamp new measurements when writing them.
Fixed C Module: pixelLineConverter, C Module: horizonOpNav, and C Module: faultDetection republishing retained measurements as fresh valid outputs and preventing downstream guidance timeout. Each input now requires an increasing message write timestamp; outputs and their timestamps are preserved between input writes so slower consumers can read the last result. Fault detection applies its modes only to fresh valid inputs in the current update.
Fixed C Module: thrForceMapping computing
outTorqAngErrand theangErrThreshsaturation scaling decision with the control frame components of the reduced torque instead of the body frame components \([C]^T[C]\mathbf{L}_r\); results are invariant under reordering the control axes or choosing another orthonormal basis for the same controlled subspace.Added a
BSK_WARNINGin C Module: thrForceMappingReset()when the configuredcontrolAxes_Bare not orthogonal.Clarified C Module: thrForceMapping documentation to distinguish commanded and saturation-clipped forces, explain nominal-thrust compensation for off-pulsing, qualify torque alignment after scaling, and describe center-of-mass updates between resets.
Monte Carlo campaigns now reuse their process pool, recycling each worker after eight simulations by default. Configure worker lifetime with
setMaxTasksPerChild()and bounded retention-queue capacity withsetRetentionQueueSize(). Writer failures now raiseRuntimeErrorand release campaign resources, including during initial-condition reruns.Removed the fixed one-second delay after each Monte Carlo run queues retained data. The controller still waits for the data writer to finish before returning.
Fixed makeDraftModule path handling and generated test imports, preserved the caller’s working directory, and protected existing module files from validation and generation failures by staging replacements.
makeDraftModule now generates smoke tests that check module execution and output message publication, including recording and write timestamps. Removed unused placeholder test parameters; add numerical payload assertions when implementing the module algorithm.
Documented the actual C and C++ template behavior with runnable Python examples, moved general RST instruction to Module RST Documentation, and added the standard documentation outline to generated module drafts.
Renamed
dummytoupdateCounteranddumVectortosampleConfigVectorin C Module: cModuleTemplate and C++ Module: cppModuleTemplate to clarify runtime state versus configuration. Update assignments, logger field names, and C++ calls tosetUpdateCounter(),getUpdateCounter(),setSampleConfigVector(), andgetSampleConfigVector(); the old names are no longer available. Reset behavior and sample calculations are unchanged.Simplified C Module: cModuleTemplate and C++ Module: cppModuleTemplate updates by removing a redundant temporary vector while retaining the linear-algebra examples, configuration interfaces, and simulation behavior.
C++ Module: fuelTank now retains Python thruster effectors and fuel-slosh particles supplied to
addThrusterSet()andpushFuelSloshParticle(), preventing dangling connections when local Python references disappear. Null connections and dynamic-thruster connections without a tank model raiseBasiliskError. Existing valid Python calls and C++ borrowed ownership are unchanged.Fixed standalone Python input-message lifetimes in the spacecraft-input configuration methods of atmosphere, magnetic-field, wind, eclipse, location, charging, MSM, and formation-barycenter models, plus
Eclipse.addPlanetToModel()andEphemerisConverter.addSpiceInputMsg(). Native readers now retain their sources until unsubscribe, replacement, or destruction, preserving existing Python call signatures. See Retaining Sources in Configuration Methods for the SWIG pattern and remaining borrowed-source requirements.DynamicObjectnow owns its integrator throughstd::unique_ptr. PythonsetIntegrator()calls andintegratorattribute access remain available, including scripts that explicitly disown a new integrator before installation; attribute assignment transfers ownership, and reinstalling the active integrator is safe. Custom C++ dynamics classes that assign raw pointers directly tointegratormust usesetIntegrator()instead. The changed C++ ownership contract increments the SDK extension ABI to version 3; compiled extensions must be rebuilt.C++ callers can pass
std::make_uniqueresults or move an existingstd::unique_ptr<StateVecIntegrator>intoDynamicObject::setIntegrator(). The raw-pointer overload and Python ownership-transfer interface remain supported; rejected replacements are consumed without replacing the active integrator.Dynamically allocated output messages in environment models, dynamics effectors, controllers, and device/visualization modules now use private
std::unique_ptrstorage. Public output-message vectors, Python indexing, subscriptions, and recorders remain available. This fixes missing cleanup in several modules and releases partially constructed output collections after allocation failures. See Vector of Output Messages for lifetime requirements; compiled extensions using the changed module layouts must be rebuilt for SDK extension ABI version 3.Added the C++
addOwnedMessage()helper inarchitecture/messaging/ownedMessage.hto create an owned output message and its borrowed view together, rolling back that insertion on failure. See Vector of Input/Output Messages for usage and the limits of this guarantee during module configuration.Extended standalone Python input-message retention to power and data storage, transmitters, downlink handling, mapping instruments, simple-antenna and albedo planet inputs, articulated facets, thruster attached-body inputs, small-body navigation thruster inputs, and Vizard camera configuration. Existing Python calls are unchanged; native readers and their copies retain each source until their subscriptions end. See Retaining Sources in Configuration Methods.
SPICE scratch buffers now clean up automatically, including when spacecraft-name validation or allocation fails.
SpiceInterface.spiceBufferandcharBufferSizeare now private; remove direct access to these internal fields from custom code. Standard simulation configuration is unchanged.SpiceInterface.getCurrentTimeString()now raisesBasiliskErrorwhen the output format would produce a buffer too short for SPICE, including five- and six-character format strings.syncDynamicsIntegration()now retains Python secondary objects and removes native synchronization links when either object is destroyed. Surviving secondaries can integrate independently again, repeated connections are a no-op, and invalid null, self, nested, or competing-primary connections raiseBasiliskError. Python calls must use the owning primary object; borrowed primary proxies are rejected before changing connections. See Lifetime of Synchronized Objects. Compiled extensions usingDynamicObjectmust be rebuilt against the updated SDK extension ABI version 3 layouts.Simulation worker records now use
std::unique_ptrand own theirstd::threadby value. Shutdown joins workers before releasing their state or changing process assignments, including exception cleanup. Normal Python thread configuration and simulation APIs are unchanged; the internalthreadListandthreadContextownership fields are no longer exposed in Python. C++ code accessing these fields must use the new owning types, and compiled extensions must be rebuilt against extension ABI version 3.Added Advanced: Multithreaded Simulations, a tutorial on configuring independent processes for multiple worker threads, with a runnable example and guidance on assignment, reinitialization, and shutdown.
SimThreadExecution::requestStop()requests shutdown and wakes an idle worker once.killThread()remains a compatibility alias, and repeated stop requests no longer add semaphore releases. Pool shutdown continues to signal every worker before joining any of them.Added Advanced: Naming Effector States and a runnable example explaining constructor-generated effector state names, object and Python-process lifetimes, and custom names for repeatable lookups across simulation builds.
Documented the existing hub and wheel mass-property accounting for all three C++ Module: reactionWheelStateEffector models, including center-of-mass and parallel-axis contributions and guidance for switching models without double-counting (issue 600).
Added the opt-in
includeWheelMassPropertiessetting to C++ Module: reactionWheelStateEffector for automatic mass, center-of-mass, inertia, energy, and momentum accounting of balanced and simple-jitter wheels with axisymmetric inertia. The default preserves existing hub accounting (issue 600).Added initialization checks for finite, positive spin inertia in every wheel model and for valid mass, transverse inertia, and imbalance inputs in fully coupled wheels, independently of the mass-accounting option.
Fixed the error message of
atmosphericDrag()inorbitalMotion, which printed the position components with an index shifted by one and read past the end of the position vector.Updated BSK-SDK Release Guide with beta and release workflows, the single-command
--refresh-exampleversion update, and nightly source verification.Reduced routine Conan, CMake, and Cargo output while preserving warnings, errors, and failure status; added a compact configuration summary, concise Rust build labels, and
python3 conanfile.py --verboseto restore detailed output. Build support-file links now create their destination first and exclude.DS_Storemetadata. See Build Output.Reduced native binding startup overhead, especially after macOS rebuilds, by grouping message, core FSW, core simulation, MuJoCo, and OpenCV bindings into separate libraries. Python imports, message recorders, optional build features, and per-module compilation are preserved.
Conan builds using Ninja or Makefile generators now export
compile_commands.jsonby default for clangd and other language servers. Xcode and Visual Studio do not support export. SettingexportCompileCommands=Falsedisables export and removes an existing database from the selected build directory.constraintDynamicEffector now rejects unsupported parent types before computing forces and torques.
Container release builds now free runner disk space before Docker setup and support rebuilding an existing release tag without moving it, with image-version and multi-architecture manifest checks.
Fixed Rust-enabled CMake reconfiguration failing when matching file timestamps retained an already-patched Corrosion build file. The loader now patches pristine cached source while preserving the shared cache and avoiding rewrites of unchanged generated content.
Fixed a lifetime issue when redirecting a C++ output to another module’s embedded output: the source module now remains alive while its storage is used by the redirected output, readers, or recorders. This includes outputs accessed through temporary MuJoCo body and site proxies. Redirecting to an output whose module has already been deleted raises
ReferenceError.Fixed C++ output-message redirection through Python assignment, restoring shared OpNav circles measurements and retaining gateway storage for producers, readers, and recorders, including inputs connected through module registration methods. Native C++ copies and moves of redirected messages take independent snapshots without consuming the gateway payload.
Fixed C++ output redirection through message vectors so indexing, front/back access, and iteration preserve the actual module owner, including iterator copies and movement after later module imports.
Redirecting to a borrowed message with an unknown storage owner, including elements of raw pointer-vector copies and slices, now raises
ReferenceError. Use the original module-owned output, a stand-alone message, or a selection fromlist(module.outputMsgs).Deferred the support-data GitHub release-tag lookup until a repository-hosted file needs downloading, eliminating this network request during imports, local and valid cached file access, and external data downloads.
Upgraded Eigen from 3.4.0 to 5.0.1, including the dependency used by OpenCV 4.14.0, and updated compiled build metadata for Eigen’s release-version format. Rebuild compiled external modules and their SDK against the matching Eigen version.
Fixed C Module: headingSuKF using the inverse camera mounting rotation for
r_BN_C. Camera-frame headings now use the body-to-camera rotation defined bysigma_CB; regression tests cover aligned cameras and 90-degree mountings about two axes.Incremental native builds now refresh
Basilisk.getBuildInfo()whendocs/source/bskVersion.txtchanges, including in existing build trees with an old Conan-cached version.Added a common native segment/view API for state, derivative, and diffusion buffers, preserving existing typed accessors and state/local-source diffusion ordering.
Added stable contiguous state, derivative, and diffusion storage allocated once after registration.
DynParamManagerretains the module-facing API;StateRegistryowns registration and native buffer access behindgetStateRegistry().Reworked fixed and adaptive Runge-Kutta bookkeeping to use preallocated flat buffers with a fixed synchronized dynamics group.
Euclidean drift candidates and adaptive truncation errors use single Eigen expressions, eliminating redundant buffer-copy passes.
State and derivative views bind directly to storage without repeated registry lookups; resets update finalized values in place.
State, derivative, and diffusion setters copy contiguous input directly while retaining support for strided matrix blocks.
Fixed Runge-Kutta can use a Euclidean buffer as its candidate buffer. Euler-Maruyama avoids diffusion packing and fuses one- and two-source Euclidean updates while preserving captured drift and local noise order.
Reaction wheels reuse derivative buffers sized during state registration.
Empty wheel and thruster effectors remain runnable without registering zero-sized state records.
Two-axis spinning-body default state and property names separate the axis and instance numbers with
_to prevent collisions with single-axis effectors. Use each effector’s public name fields when accessing these records.Release builds use the toolchain’s default optimization flags without appending an
-O2override.Fixed and adaptive Runge-Kutta permit compiler-dependent rounding differences, including fused multiply-add. Numerical compatibility is evaluated with accuracy tolerances.
Migrated all stochastic integrators to finalized indexed noise topology and preallocated workspaces. Noise counts can be declared through
StateSpecor the deprecated registration-timeStateData.setNumNoiseSources()compatibility API.Shared stochastic sources preserve each state’s local increment order, including noncommutative update policies and Euclidean rounding.
Native
StateBuffers,StateBufferKind, andStateBufferSegmenttypes describe contiguous storage and borrowed scalar ranges.Simplified stochastic buffer views and validation, and reduced RKMil’s packed arithmetic passes while retaining its inline Euclidean update path.
Borrowed VSCMG configuration elements retain their owning Python effector through both indexed collection access and
getVSCMGAt().Stochastic methods that only use Wiener increments no longer draw unused auxiliary Gaussian values. Seeded trajectories from these methods therefore differ from earlier releases.
Replaced MuJoCo’s specialized scene-wide qpos state with buffer-backed, manager-owned records associated with each joint, quaternion update policies, and fixed-layout validation during model recompilation.
Removed
StateVector,ExtendedStateVector, standalone or subclassedStateDataconstruction and arithmetic, and mutable error-control flags. DeprecatedgetStateReference()andgetStateDerivReference()names remain as borrowed const-view aliases and will be removed after September 30, 2027. UsestateView()andderivativeView(), respectively.Standalone
DynParamManagerusers callfinalizeStates()after state declarations and before integration. Later declarations reuse existing states by name; shapes and noise connections remain fixed. Setup errors propagate without Reset rollback.Python keeps
registerState(nRow, nCol, stateName)and exposes complete specifications throughregisterStateSpec(stateName, spec). Embedded managers and callback-created states retain their borrowed-lifetime contracts; callers keep the owning dynamics object or scene alive.SWIG uses declaration-local ownership hooks and canonical imports. Both
setIntegrator(method)andintegrator = methodtransfer newly supplied integrators, including rejected replacements. Synchronized secondaries remain retained by Python, and native destruction detaches connections before later propagation.Adaptive Runge-Kutta tolerances can be configured with the compatibility
relTolandabsTolproperties or withsetRelativeTolerance()andsetAbsoluteTolerance().C++ callers should replace direct
DynamicObject::integratorreads withgetIntegrator(),isDynamicsSyncedreads withgetIntegrationOwner() != nullptr, and mutableStateVecIntegrator::dynPtrsaccess with the read-onlygetDynamics()view.C++ callers should configure MuJoCo attitude integration with
setHighOrderAttitudeIntegration()before reset; Python retains thehighOrderAttitudeIntegrationproperty.Allocation-regression tests intercept C++ and C allocation APIs on macOS and ELF platforms. MSVC validation is explicitly partial because it covers C++ operators and Eigen’s runtime allocation guard but cannot robustly interpose every CRT allocator.
Added an architecture guide and subsystem/API documentation covering state ownership, initialization, binding, RK workspaces, shared noise, MuJoCo policies, and Python compatibility. Matching resets initialize existing state buffers in place. Replacing an integrator destroys the old object, invalidating its borrowed pointers.
Moved the existing 2.13 beta known-issue entries into individual RST snippets, preserving their text, order, and compact bullet formatting. Earlier tagged-release sections remain in the known-issues page.
Split known issues into version-series pages, preserving the historical entries and existing bookmarks, and organized the 2.12 and 2.11 entries by topic. Contributors continue using the same known-issue snippets; maintainers finalize tagged releases in the matching series page and group longer lists under topic headings.
Known-issue updates now use individual RST snippets under
docs/source/Support/bskKnownIssuesSnippets, reducing conflicts between unrelated PRs. Release notes and known issues share a compiler that runs automatically during Sphinx builds; maintainers review and archive both collections before a tagged release.Full documentation builds reject nonempty snippet collections without an active include, preventing new entries from being omitted after release finalization. Update pending known-issue entries when their descriptions change, and use new snippets for follow-ups to published history.
Known-issue entries cover issues affecting tagged releases. Issues introduced and fixed entirely within the same beta cycle need no known-issue entry if no tagged release was affected; release-note requirements apply separately.
Fixed C++ Module: lambertSolver remaining disabled after an aligned input: alignment rejection now applies only to the current update, allowing subsequent acceptable geometry or a relaxed alignment threshold to recover on the same module instance without a reset.
Added numeric input validation to C++ Module: lambertSolver: nonfinite or nonpositive flight time and gravity, and endpoint vectors with nonfinite components or zero/nonfinite computed norms now raise
BasiliskErrorbefore solving. Alignment thresholds must be finite and strictly between 0 and 90 degrees; rejected setter values preserve the previous configuration. A componentwise roundoff bound rejects parallel and antiparallel endpoints even when normalization leaves a tiny nonzero cross product. Alignment rejection precedes geometry and flight-time scaling to avoid invalid square roots and division by zero.Fixed the intermediate zero-revolution Izzo starter in C++ Module: lambertSolver and its Python test reference by correcting the logarithmic interpolation exponent, reducing unnecessary iterations and avoiding default C++ Module: lambertValidator iteration-limit rejection for affected transfers near the parabolic boundary. The Python reference also handles rounded parabolic starters without producing NaN results.
Fixed C++ Module: lambertSolver raising the
FE_INVALIDfloating-point flag while rejecting quiet NaN endpoint positions on x86 platforms; input validation now classifies each component before computing norms or geometry.Fixed C++ Module: lambertSolver publishing unconverged roots as valid by safeguarding both root searches and checking convergence and finite velocities; failed branches now return zero velocities and cleared validity flags. The safeguards preserve useful high-order steps before and after bisection, accurate starters, and converged corrections, resolve near-parabolic flight times with a smooth evaluator, and allow additional bounded iterations for difficult transfers.
C++ Module: lambertSolver now raises
BasiliskErrorfor unknownsolverMethodvalues before solving.LambertProblemMsgPayload.solverMethodis anintvalidated before conversion to the internal enum; C++ callers assigning this field to aSolverMethodvariable must validate and explicitly cast it. ExistingIZZO(0, the default) andGOODING(1) selections and planner APIs are unchanged, and corrected requests can recover without resetting the solver.On Python 3.15,
SimulationBaseClassdefers its Matplotlib imports until plotting functionality is used, reducing startup work for simulations that do not draw diagrams. Python 3.9–3.14 retain eager imports and the same plotting interfaces.Improved the correctness, numerical stability, buffer safety, and performance of linearAlgebra while retaining its pure-C implementation and public API; expanded regression tests and API documentation (GitHub issue 1646).
ArchitectureUtilitiesnow requires a C11-capable compiler.Avoided a macOS pipe-buffer deadlock during editable-install and wheel source discovery by passing Git attribute queries as bounded command-line argument batches, preserving existing packaging dependency ranges and Git export rules.
Documented message-lifetime limits for output redirection: configure wiring before simulation, retain participating modules, and use stand-alone gateways for redirected feedback connections. Native ownership cycles remain unsupported and are not automatically detected.
Clarified that camera and Vizard image buffers belong to their producers and must be consumed before replacement; message recorders do not archive the image bytes.
Updated the optional MuJoCo dependency from 3.11.0 to 3.17.0.
macOS builds refresh the MuJoCo framework path after dependency upgrades, keeping the linked library consistent with its headers.
MJScene XML exports compile pending model edits before saving and report file-writing errors instead of silently omitting the output.
Fixed a buffer overflow in headingSuKF covariance updates.
Corrected horizonOpNav planet selection and added errors for unsupported planet IDs.
Fixed zero-noise operation in hingedRigidBodyMotorSensor.
Corrected the initial state dimension in
scenarioSmallBodyNav. Invalid state and covariance or noise matrix dimensions in smallBodyNavEKF now raiseBasiliskErrorin Python.Fixed Ninja Multi-Config builds failing on C message interface dependencies and preserved configured C message sources across native clean operations.
Fixed import-order-dependent numeric-vector binding errors affecting storage-message reads after importing C++ Module: simpleInstrument,
zeroWindModel.VectorDouble, and C++ Module: linkBudget lookup tables. Indexing, slicing, and mutation now work with the shared messaging vector without changing the native ABI.Updated the C++ Protobuf dependency to 6.33.5 and OpenCV to 4.14.0, replacing the unsupported Protobuf 3.x runtime while retaining the Vizard message schema and Python 3.9 support. Source builds now require Conan 2.4.0 or newer, and the Python Protobuf dependency now requires version 6.33.5 or newer.
Fixed incremental builds retaining an incompatible cached Protobuf compiler after a dependency upgrade.
Added standard CPython 3.15 support while retaining Python 3.9 through 3.14. Python 3.15 uses NumPy 2.5.2 or newer and Numba 0.68 for examples and development; older interpreters retain their dependency ranges. Native message bindings explicitly target the NumPy 1.24 C API so Python 3.15-built wheels remain compatible with NumPy 1.24.4 on older interpreters. Updated source-build CI and wheel tooling, and moved the existing wheel installation checks to Python 3.15.
Updated Python runtime, build, test, and documentation dependency upper limits to versions validated by the October 17, 2026 canary build, preserving the existing minimum versions and allowing compatible releases on older supported Python versions.
Included Numba in development requirements and required Numba 0.67 or newer on Python 3.12 and newer, preventing NumPy 2.5 upgrades from leaving an incompatible Numba installation in existing development environments.
The build script now rejects unsupported Python versions before starting build operations, and CMake validates its selected interpreter against the same
project.requires-pythonrange inpyproject.toml.Split release notes into version-series pages and a single archive for versions before 2.0.0, preserving historical release bookmarks and the manual release workflow.
Removed the obsolete
StateEffector.receiveMotherSpacecraftData()method and itsr_BP_Panddcm_BPfields following the removal ofSpacecraftSystem. Hub and hinged-body calculations now use their configured body-frame geometry directly; prescribed-motion transformations remain supported.Removed the unused
prependSpacecraftNameToStates()hooks from state and gravity effectors and the obsoleteGravityEffector.nameOfSpacecraftAttachedTo,StateEffector.nameOfSpacecraftAttachedTo, andStateEffector.parentSpacecraftNamefields. These supported the retiredSpacecraftSystemshared state manager; remove calls, overrides, and field assignments in custom effectors, and use the configured state and property names directly without adding a spacecraft prefix. Prescribed-motion attachments continue to use explicit property names assigned byaddStateEffector()and no longer request an unused hub-attitude state. Vizard’s separateparentSpacecraftNamefield is unchanged.Removed the deprecated
spacecraftSystemmodule, includingSpacecraftSystem,SpacecraftUnit, andDockingData, after its one-year deprecation period. Use C++ Module: spacecraft with C++ Module: constraintDynamicEffector to connect spacecraft; see scenarioConstrainedDynamics.Group the example-script sidebar by its existing topic headings, with collapsible categories and automatic expansion for the current scenario.
Added optional viewing-angle and geometric specular-glare access limits to C++ Module: spacecraftLocation for optical observation planning (issue #864).
Corrected C++ Module: spacecraftLocation Sun and viewing directions to originate at the configured body-fixed location; the viewing angle is now reported without a Sun input (issue #864).
Reject NaN glare thresholds in C++ Module: spacecraftLocation during initialization so invalid settings cannot silently bypass glare rejection (issue #864).
Enabled strict compiler diagnostics by default for Basilisk C and C++ sources through Conan and CMake. Use
--strictWarnings False, Conan’s-o "&:strictWarnings=False", or CMake’s-DBSK_STRICT_WARNINGS=OFFto disable the additional diagnostics; see Strict Compiler Warnings.Resolved GCC and MSVC diagnostics, including conflicting Windows warning flags. Unsupported planet identifiers in
pixelLineConverter,pixelLineBiasUKF, andrelativeODuKFnow raise a Basilisk error instead of using uninitialized planet constants.Corrected Windows exception handling so fatal errors from C modules propagate to Python as
BasiliskErrorinstead of aborting the process.Fixed Python interpreter aborts in shared SWIG iterator element access and boundary-error handling that depended on module import order. Native class layouts and the messaging ABI are unchanged.
Fixed import-order-dependent SWIG conversion failures for shared
DoubleVectorandMultiArrayobjects when usingsvIntegratorsalongside gravity or MuJoCo bindings. Python-list inputs remain supported.Fixed C Module: thrForceMapping returning positive off-pulsing commands with a deterministic fallback that minimizes controlled torque error, then force norm without cycling at zero-force boundaries; roundoff-sized sign errors are clamped, and valid allocations and the existing
angErrThreshsaturation policy are preserved.Updated Usage Metrics with a daily updated total and trend plot of recorded requests for known BSK
.whlfiles from all clients except identified mirrors, including coverage dates and counting limitations.Fixed Visual Studio 2026 clean failures caused by an absolute path in the C-message target’s solution folder.
Wheel workflows now resolve stable Rust once per run and share the exact toolchain across core and opNav builds, preventing packaging failures caused by runner toolchain drift.
Upgraded zlib to 1.3.2 and optical navigation builds to libpng 1.6.58, removing their legacy Conan metadata warnings. The libjpeg and cppzmq dependencies are unchanged.