(sec-issuetracker)= # Issue tracker This section contains resolved issues per release and known bugs. Use this information to understand changes compared to previous versions. The extension `.dev1` is not added in the issues list (e.g., 1.2.2.dev1==1.2.2), as it only marks versions that will not be available in pypi with standard pip install, but only with the `--pre` option or by specifying the exact version name, see versions on . Every entry carries the **type** of the issue, then its **priority** and its **effort** as badges (`LOW EFF` is within 2 hours, `MEDIUM EFF` is within 16 hours, `HIGH EFF` is within 40 hours, `HUGE EFF` is above 40 hours), then who raised it and who resolved it - both omitted when that was Johannes Gerstmayr (JG). General information on current version: - Exudyn version = 1.13.6 - last change = 2026-10-09 - Number of issues = 2921 - Number of resolved issues = 2783 (6 in current version) ## Resolved issues and resolved bugs before version 1.13 The following list contains the issues which have been **RESOLVED** in the according version. The issues of the current release, 1.13, are in the {ref}`changelog `. ### Version 1.12 - **1.12.462** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` installation page: pip install -i https://pypi.org/project/ exudyn is not a valid index URL (#2910) - description: PDF check 2026-10-09. The simple index of PyPI is https://pypi.org/simple. revision2026b step RG3.43 - **notes:** The installation page names a valid package index for pip, https://pypi.org/simple - date resolved: **2026-10-09 11:33**, date raised: 2026-10-09 - **1.12.461** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` generated signatures end in -\> exudyn.ObjectInde) - the return annotation loses its last letter (#2909) - description: PDF check 2026-10-09: 'exudyn.ObjectInde)' in PDF and online, multiple times: CreateGround(mbs, ...) -\> exudyn.ObjectInde). GetFunctionArguments cuts the def line at a fixed place. revision2026b step RG3.43 - **notes:** The function signatures of the documentation show return annotations completely, e.g. CreateGround(...) -\> exudyn.ObjectIndex - date resolved: **2026-10-09 11:33**, date raised: 2026-10-09 - **1.12.460** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` LaTeX umlauts in the manual: Gr"ubler-Kutzbach, Br"uls (#2908) - description: The maintainer, checking the PDF before 1.13 (2026-10-09): 'In the docs/theory section I found a couple of Gr”ubler-Kutzbach typos to be fixed. Please check and fix all such "o, "a and "u in the document.' Leftovers of the LaTeX conversion in theoryMultibody.md, solver.md, introduction.md and the module headers of FEM.py and kinematicTree.py (generated pages). revision2026b step RG3.42 - **notes:** The manual writes Grübler, Brüls, Schöberl, Zwölfer and Plücker with their letters instead of LaTeX accents, and the documentation check refuses a LaTeX accent in text - date resolved: **2026-10-09 10:21**, date raised: 2026-10-09 - **1.12.459** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` macOS: after Q or ESCAPE in the SolutionViewer, its window and a 'tk' window stay visible and empty (#2906) - description: macOS GUI check 2026-10-08, S7: after Q or Escape in the dialog, the SolutionViewer and a tk window remain visible but empty. Cocoa removes a destroyed GLFW window only when its events are processed, and a destroyed Tk window stays until Tk processes its events; the 'tk' window is the root left by the failed dialog of R6 (\#2904). revision2026b step RG2.4.6.3 - **notes:** macOS: the render window and the SolutionViewer leave the screen when they are closed; confirmed on the Mac - date resolved: **2026-10-09 08:25**, date raised: 2026-10-08 - **1.12.458** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the test suite of the GitHub wheels cannot fail: cibuildwheel test-command without --exit-code (#2907) - description: The test-command of \[tool.cibuildwheel\] (Linux, macOS, Windows) runs runTestSuite.py -quiet -local without --exit-code, so a failing test suite leaves the wheel job of .github/workflows/wheels.yml green; the GitLab job passes it. Maintainer 2026-10-09: 'yes, add the --exit-code'. revision2026b step RG10.24 - **notes:** The test suite run by the GitHub wheel builds (cibuildwheel) passes --exit-code, so a failing suite fails the wheel job - date resolved: **2026-10-09 08:14**, date raised: 2026-10-09 - **1.12.457** `FIX` `HIGH EFF` `resolved by: Claude-JG` linux (#2140) - description: fix graphics-related crashes on linux versions, in particular when closing renderer and with mbs.SolutionViewer() - **notes:** No more crashes of the renderer or the SolutionViewer on Linux: a larger number of tests by the maintainer could not reproduce them - date resolved: **2026-10-08 20:01**, date raised: 2025-07-10 - **1.12.456** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` real-time mode: the time of a pause counts, the simulation jumps when it continues (#2905) - description: macOS GUI check 2026-10-08, K5: in real-time mode the simulation time runs on while paused; paused at 9 s, waited 5 s, continued: it jumps to 14 s and continues in real time. CSolverBase: the real-time pacing compares the simulated time with the wall-clock time since the start of the solver, pauses included (on every platform); and the realtime.factor is applied to the first value only, not inside the waiting loop. revision2026b step RG2.4.6.2 - **notes:** Real-time mode: a pause (SPACE, pauseAfterEachStep) no longer counts as simulated time, the simulation continues where it was paused; realtime.factor holds while the solver waits - date resolved: **2026-10-08 19:15**, date raised: 2026-10-08 - **1.12.455** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` right click on a sensor: the properties dialog fails (ShowRightMouseSelectionDialog: showing the dictionary failed) (#2904) - description: macOS GUI check 2026-10-08 (tmp/MacOS/GuiManualCheckMacOS.txt), R6 with Sensor0 of guiManualCheckModel.py: ERROR: ShowRightMouseSelectionDialog: showing the dictionary failed, then an abort in plt.show of phase 5. Reproduced on Windows: TkinterEditDictionary.GetDictionary takes self.tree.item(i,'values')\[0\], and for an empty value - fileName '' of a sensor - Tk gives '' instead of a tuple: IndexError. The broad except printed no reason. The Tk root the failed dialog left behind is the empty 'tk' window of S7 and plausibly the abort under the macosx backend of matplotlib. revision2026b step RG2.4.6.1 - **notes:** The properties dialog of a right click works for items with an empty value, e.g. a sensor without a file name; a failure of the dialog names its reason - date resolved: **2026-10-08 19:15**, date raised: 2026-10-08 - **1.12.454** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` spotReinforcementLearning.py imports RL\_Spot, which is not in the repository; checkExtras keeps a rotted exemption for exudynCPP (#2903) - description: Complete build of 2026-10-08, checkExtras warnings: broken import RL\_Spot in Examples/FurtherExamples/spotReinforcementLearning.py - the model of that folder is spotModel.py with the same GetModel(addShoulderContact) (the Details line names it); and the exemption of exudynCPP is used nowhere. revision2026b step RG10.23.3 - **notes:** spotReinforcementLearning.py imports spotModel, the model of its folder, instead of the missing RL\_Spot; checkExtras reports no warnings - date resolved: **2026-10-08 18:46**, date raised: 2026-10-08 - **1.12.453** `TESTING` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` pytest files use deprecated helpers where they do not test a deprecation (#2902) - description: Complete build of 2026-10-08: DeprecationWarnings of graphics.BrickXYZ (test\_graphicsMiniExamples.py, test\_zoomAllTrackMarker.py) and beams.GenerateStraightLineANCFCable/2D (test\_itemCompatibility.py); these tests do not test the deprecations. revision2026b step RG10.23.2 - **notes:** The pytest files use graphics.Brick and GenerateBeamElementsAlongLine where they do not test a deprecation - date resolved: **2026-10-08 18:46**, date raised: 2026-10-08 - **1.12.452** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the quiet exudev build shows pip's message on conflicting packages as an ERROR line without the conflicts (#2901) - description: Complete build of 2026-10-08 (tmp/completeBuild2026-10-08.txt), venvP313: ERROR: pip's dependency resolver does not currently take into account all the packages that are installed ... - the quiet filter of \#2895 passed the first line (it contains error) and swallowed the conflicts listed after it (spyder-kernels 2.5.0 for spyder 6.1.2, setuptools 72.1.0 for sip). Not an error of the build. revision2026b step RG10.23.1 - **notes:** The quiet exudev build shows pip's message on conflicting packages in the environment as a note with the conflicts, instead of an ERROR line without them - date resolved: **2026-10-08 18:46**, date raised: 2026-10-08 - **1.12.451** `TESTING` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev build --complete stops at the test suite of Python 3.10: energiesTest.py differs by 5.9e-11 with numpy 2.2 (#2900) - description: The local complete build of 1.12.450 (2026-10-07/08): wheels for cp310-cp314 built, then the test suite in venvP310 failed with energiesTest.py: 17.61488435881711 against 17.614884358875663, error -5.855e-11 (rel. 3.3e-12), tolerance 5e-14; the build stopped there, so 3.11-3.14 and the fast module were not tested. The same difference was seen on Linux (WSL 1.12.372) and put into UnresolvedOnLinux; venvP310 has numpy 2.2.5, the reference environment numpy 2.4.6 - a round-off difference, not a platform one. revision2026b step RG4.1.4 - **notes:** exudev build --complete passes again: energiesTest.py gets a tolerance factor for the round-off difference of numpy 2.2, and seven performance references follow the modified Newton default of the time integration (\#2815) - date resolved: **2026-10-08 08:51**, date raised: 2026-10-08 - **1.12.450** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` visualizationSettings.bodies.shells.inPlaneTiling: the subdivision of plates and shells in the drawing (#2899) - description: The maintainer, 2026-10-07, testing the ANCF thin shells: 'there is no option in visualizationSettings.shells on how often plates/shells are subdivided in drawing - like a inPlaneTiling, per default 4 I would suppose. The cross-section tiling is currently less critical as it is probably linear. I also see that it probably does not use the 6-node triangles (which however would not help a lot, because for contour, the main problem is the subdivision for the values, not for the shape).' The plate used bodies.beams.axialTiling (default 8). revision2026b step RG6.17 - **notes:** Plates and shells (ObjectANCFThinPlate) are drawn with their own subdivision, visualizationSettings.bodies.shells.inPlaneTiling (default 4 x 4 quads per element), instead of the axial tiling of the beams - date resolved: **2026-10-07 22:38**, date raised: 2026-10-07 - **1.12.449** `FIX` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the scaling of the render window and the dialogs, restarted: system scaling times displayScaleFactor for the renderer, the scaling of Tk plus dialogs.fontScaling for every dialog (#2898) - description: The maintainer's measurements on Ubuntu with fractional scaling 200 percent, 2026-10-07 (after \#2897): displayScaleFactor 0 / fontScaling 0: render window scaled, the settings tree scaled, but buttons and edit fields very small, help and command dialogs not scaled; displayScaleFactor 1: dialogs scaled with buttons and edit fields large (looks best), render window unscaled; fontScaling 0.5: all dialogs 2x smaller, buttons tiny; at 100 percent a displayScaleFactor 0.5 made the buttons huge. 'I would suggest to kind of restart the scaling thing ... a conservative approach ... check at which places these factors take effect ... consider that some tkFonts already scale with the linux fractional scaling, so double scaling is contraproductive ... write up a table'. revision2026b step RG6.16 - **notes:** The render window scales with the display scaling of the system times general.displayScaleFactor; every dialog - settings, help, command window, buttons and edit fields included - follows the system scaling, and dialogs.fontScaling is a factor on top of it; confirmed on Ubuntu with fractional scaling - date resolved: **2026-10-07 21:37**, date raised: 2026-10-07 - **1.12.448** `CHECK` `LOW EFF` `resolved by: Claude-JG` linux GLFW (#2277) - description: check if glfwGetWindowContentScale now works on newer GLFW version to enable display scaling on linux - **notes:** On Linux the display scaling of the system (also fractional scaling) is read through GLFW 3.3.6 or newer and scales the render window and the dialogs; confirmed on Ubuntu - date resolved: **2026-10-07 21:37**, date raised: 2026-02-09 - **1.12.447** `CHANGE` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` one display scaling setting: general.displayScaleFactor (0 = system, \> 0 = override); the dialog fonts of fontScaling for all widgets; after-callbacks of closed dialogs (#2897) - description: The maintainer's check on Ubuntu, 2026-10-07: scaling is improved; the display scaling provided by Ubuntu works perfectly, so merge the factors: displayScaleFactor = 0 uses the scaling of Windows, Linux (macOS if possible), \> 0 overrides; useWindowsDisplayScaleFactor and linuxDisplayScaleFactor deprecated (the linux value mapped to the new one, the windows value to a dummy). dialogs.fontScaling rescales only the inner text, not the buttons or the edit fields, and it rescales while the window opens; values \< 1 were used too. 'invalid command name ...\ while executing (after script)' after closing dialogs. A crash 'X Error of failed request: BadWindow (X\_QueryTree)', 'terminate called without an active exception' after changing a few parameters and re-opening. revision2026b step RG6.15 - **notes:** One display scaling setting, general.displayScaleFactor: 0 uses the scaling of the system (Windows, Linux, macOS), a value \> 0 replaces it; useWindowsDisplayScaleFactor and linuxDisplayScaleFactor are deprecated. dialogs.fontScaling applies to every widget of the dialogs, buttons and edit fields included, and closing a dialog no longer leaves invalid command name messages - date resolved: **2026-10-07 18:47**, date raised: 2026-10-07 - **1.12.446** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` InverseKinematicsNumericalExample.py fails: InverseKinematicsNumerical.Solve returns None for the joint values (#2896) - description: Found by the examples run of 1.12.443 (2026-10-07): TypeError: unsupported operand type(s) for \*: 'NoneType' and 'float' in np.round(sol\[0\], 3) at line 72 - the solution of myIkine.Solve(T3, q0=...) is None. The example passed in the runs up to 1.12.279; the robotics classes were changed to exu.HT in between (\#2821). Not investigated yet. - **notes:** InverseKinematicsNumericalExample.py solves a reachable pose again (the pose of a known configuration), and InverseKinematicsNumerical.Solve no longer fails on rounding the joint values of a failed solve - date resolved: **2026-10-07 18:47**, date raised: 2026-10-07 - **1.12.445** `FIX` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` Ubuntu: fractional scaling not followed by the renderer, linuxDisplayScaleFactor without effect, dialogs.fontScaling not in the H and X dialogs (#2893) - description: The maintainer's check on Ubuntu, 2026-10-07: 'general.linuxDisplayScaleFactor does nothing (can be removed?); dialogs.fontScaling works for the visualizationSettingsDialog, but not for the other dialogs (X, H); the linux settings Fractional Scaling affects the dialogs font sizes, but not the renderer's =\> fix if possible; the renderer's font size can be adjusted currently with the view0.window.globalFontSize.' revision2026b step RG6.14 - **notes:** Fractional and other display scaling on Linux scales the texts of the render window and the dialogs (GLFW 3.3.6 or newer); confirmed on Ubuntu - date resolved: **2026-10-07 18:47**, date raised: 2026-10-07 - **1.12.444** `IMPROVEMENT` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` quiet runs: the build shows its version and a progress line, the test runners a progress line and no tables; the test suite log 260000 lines of caught user errors (#2895) - description: The maintainer, 2026-10-07: 'for the exudev build command, it would be extremely helpful to see in the console which exudyn version is built, and to see a progress during compilation ... The same would be nice for TestModel and Example runs (in quiet case). For the test suite, after the run finishes with python tools/exudev test --env venvExuP313 it outputs a lot of text =\> should be the quiet case by default. Furthermore, the log file for the testsuite has, since about version 1.12.366, approx. 260000 lines after TESTMODEL 138 parameterConversionTest.py which is unacceptable (User ERRORs =\> we need a solution (turn off by environment setting/config.special flag, etc.)' revision2026b step RG10.22 - **notes:** Quiet runs: exudev build names the Exudyn version and counts the compiled files in one line; the test suite and the examples count the models in one line and end with their summary; exudyn.special.exceptions.writeErrorsToLogFile keeps caught errors out of the log (the test suite log: 7000 instead of 266000 lines) - date resolved: **2026-10-07 18:19**, date raised: 2026-10-07 - **1.12.443** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` docs job of GitLab CI fails: the generated page of a new test model was not committed (#2894) - description: GitLab docs job on ca70704f (tmp/gitlabRunsFailed/output.txt): docs/generated/testModels/testModelsIndex.md:7: WARNING: toctree contains reference to nonexisting document 'docs/generated/testModels/fileHeaderThreadsTest' - with -W one warning fails the build. The page was generated with \#1450 but left untracked (git add -u adds no new files); regenerate.py reported it as a tier 2 warning only. Fix: commit the page; regenerate.py --check fails for a new generated file git does not know. revision2026b step RG10.21 - **notes:** The documentation builds from a fresh clone again: the page of the test model fileHeaderThreadsTest is committed, and the regeneration check fails for a newly generated page that is not in git - date resolved: **2026-10-07 17:47**, date raised: 2026-10-07 - **1.12.442** `CHECK` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` tkinter dialogs look awkward on Ubuntu: the Tk of conda on Linux has no Xft (#2890) - description: The maintainer, 2026-10-07: 'as I have now also the build config for Ubuntu: I could test now improvements for font scaling (or fonts in general - they look awkward on ubuntu). If you include a setting (like for activating font scaling on linux, or coupling it temporarily for macos), I could test, if it works now.' Two settings to test, default off: general.useDisplayScaleFactorOnLinux (glfwGetWindowContentScale on linux, \#2277) and general.useTextMipmaps (the 64-pixel characters of the bitmap font minified with mipmaps instead of 2x2 linear sampling). After the tests: defaults decided, or the settings removed. revision2026b step RG6.13 \[2026-10-07, Claude-JG\]: Correction by the maintainer, 2026-10-07: 'It is not about the renderer text - that is perfect, but the tkinter dialogs.' The two renderer test settings are removed again. Cause found: the libtk8.6.so of the conda environments (tk 8.6.14/8.6.15 of the default channel) links no Xft, so Tk draws with X11 core fonts - no anti-aliasing, few sizes; the system Tk links libXft. Fix: the Xft build of conda-forge, conda install -c conda-forge 'tk=\*=xft\_\*'; the dialogs say so once on Linux when Tk reports fontsystem x11. - **notes:** On Linux with conda, the dialogs draw smooth fonts with the Xft build of tk from conda-forge; Exudyn says so once, and the installation page has a section Working with Ubuntu - date resolved: **2026-10-07 16:42**, date raised: 2026-10-07 - **1.12.441** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` UBSan: mbs.ComputeItem casts every object to CObjectBody (#2892) - description: The sanitizer job of GitLab CI (b834538a, gcc 14, test suite exit 0, AddressSanitizer 0, one UB report): src/Main/MainSystem.cpp:1242:29: runtime error: downcast of address ... which does not point to an object of type 'CObjectBody'. MainSystem::PyComputeItem cast the object to CObjectBody before the switch, also for connectors and constraints; the cases that use the body apply to bodies alone, so the pointer was never used for another object, but the cast itself is undefined behaviour. revision2026b step RG4.25 - **notes:** mbs.ComputeItem casts an object to a body only if it is one; the sanitizer build reported the cast of connectors and constraints as undefined behaviour - date resolved: **2026-10-07 16:23**, date raised: 2026-10-07 - **1.12.440** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev accepts Python 3.15 and 3.16 when named (--py 315, venvP315) (#2891) - description: The maintainer, 2026-10-07: 'the exudev and similar scripts only work until 3.14. Please also allow Python 3.15 and Python 3.16 with 315 and env venvP315, etc., keeping the standard still with 3.10-3.14.' revision2026b step RG10.20 - **notes:** exudev accepts --py 315 and 316 (also 3.15, P316) with the environments venvP315 and venvP316; --py all stays the version matrix 3.10-3.14 - date resolved: **2026-10-07 16:02**, date raised: 2026-10-07 - **1.12.439** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ffmpeg for the videos: conda install ffmpeg and pip install ffmpeg-python on every platform (#2889) - description: The maintainer, 2026-10-07: 'for installation of ffmpeg, for the according places in the docs, please add: conda install ffmpeg (install ffmpeg in general); pip install ffmpeg-python (install python package). Tested on MacOS and linux. This removes the necessity for homebrew on mac (which takes very long); and it directly runs in the terminal.' revision2026b step RG3.41 - **notes:** Videos from recorded frames: the documentation and the messages of exudyn.interactive name conda install ffmpeg and pip install ffmpeg-python, which work on Windows, Linux and macOS without Homebrew - date resolved: **2026-10-07 14:29**, date raised: 2026-10-07 - **1.12.438** `TESTING` `raised by: Claude-JG` `resolved by: Claude-JG` Ubuntu GUI check: curved triangle tiling and recorded frames not reproduced from here (#2881) - description: exudynGuiCheckUbuntu.txt: K13 - openGL.advanced.curvedTriangleTilingAngle 90/5/15 shows no visible difference in graphicsCurvedShapes.py; S6 - Record frames in the SolutionViewer wrote no images (no images folder). Both need a screen: to be repeated with 1.12.37x (a failed PNG write is now reported in the console; the images go to images/ in the directory the script was started from), and the tiling compared with Windows. - **notes:** On Ubuntu the curved triangles follow the tiling angle (K13) and Record frames in the SolutionViewer writes its images (S6): the frame is read before the buffer swap, the first frame prints where it is written, a failed write is reported - date resolved: **2026-10-07 14:22**, date raised: 2026-10-06 - **1.12.437** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` GETTING\_STARTED.md: exudev started as 'python -m exudev', which fails; the README does not point to the page (#2888) - description: The maintainer, 2026-10-07: 'python -m exudev build --env venvExuP313 =\> this is I believe wrong, it should be: python tools/exudev build ... Please check all commands in the getting started. It also should really help when starting up. The getting started document should also be linked from the README.md and README.rst in the repo root. Think about, if somebody clones the gitlab repo, the only info one has is the README.' revision2026b step RG3.40 - **notes:** The developer getting-started page starts the driver as python tools/exudev (python -m exudev fails without tools/ on the path), says what to do when conda is not found, and README.md and README.rst point to it - date resolved: **2026-10-07 14:09**, date raised: 2026-10-07 - **1.12.436** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` Record frames in the SolutionViewer writes no images, at random: saveImageAsData not initialized (#2887) - description: Found by the GUI check agent on Ubuntu over xrdp (S6, HEAD c3327c06): RenderViewDataVSC::saveImageAsData was never initialized and InitializeRenderState did not reset it; with a nonzero value SaveSceneToFile took the RedrawAndGetImage() path and returned before the directory or the file was written - no images folder, no error, only the message of the first frame. Random by nature (guiManualCheckModel.py failed 2/2, a minimal script worked). Second: in data mode SaveImage built a file name, counted the frame and printed it, so a RedrawAndGetImage() before a recording used up frame00000 and announced a file that never existed. revision2026b step RG2.4.5.1 - **notes:** Record frames in the SolutionViewer writes its images every time: the flag that keeps a frame in memory for RedrawAndGetImage() is initialized, and RedrawAndGetImage() no longer uses up a frame number - date resolved: **2026-10-07 12:54**, date raised: 2026-10-07 - **1.12.435** `EXTENSION` `HIGH` `MEDIUM EFF` `resolved by: Claude-JG` coordinatesSolution (#1450) - description: add number of threads to solution files and more details on computer; check parameter variation and other files (e.g. numberOfThreads and final computation time) - **notes:** The version line of the solution and sensor file headers ends with the number of threads of the computation, e.g. '\#Exudyn version = 1.12.435.dev1; Python3.13.2; Windows x86\_64 FLOAT64; 4 thread(s)' - date resolved: **2026-10-07 12:05**, date raised: 2023-02-25 - **1.12.431** `CHECK` `LOW EFF` `resolved by: Claude-JG` linux GLFW (#2278) - description: check if call to glfwDestroyWindow from StopRenderer avoids crashes on linux? - **notes:** On Linux no more crashes when the renderer is closed; confirmed by the maintainer's tests on Ubuntu (2026-10-07) - date resolved: **2026-10-07 10:59**, date raised: 2026-02-09 - **1.12.417** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` pip install --group dev fails on macOS and on Python 3.14+: scipy==1.15.2 has no wheel there (#2886) - description: The maintainer, 2026-10-07: on macOS with Python 3.14 and 3.15 'pip install --group dev' does not work with the scipy restriction to 1.15 - it cannot be installed; remove the restriction for macOS in general, and for the newer Python versions use the current scipy. The pin of the dev group gets PEP 508 markers, as tools/ci/buildManylinux.sh already has for 3.14. revision2026b step RG10.19 - **notes:** pip install --group dev works on macOS and on Python 3.14+: the dev group pins scipy==1.15.2 only where it has wheels (not macOS, Python \< 3.14) and takes the current scipy elsewhere - date resolved: **2026-10-07 10:53**, date raised: 2026-10-07 - **1.12.416** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev issue html writes the HTML overview of the tracker (#2885) - description: tools/issueTracker/trackerlog.html is ignored by git and only written as a side effect of a verb that changes an issue, so a fresh checkout has none. The maintainer, 2026-10-07: 'when I checkout the repo at another computer: I do not have the html page of the issue tracker (which is handy)' - a verb that writes just this page. revision2026b step RG10.18 - **notes:** exudev issue html writes the HTML overview of the tracker, tools/issueTracker/trackerlog.html, which git ignores - e.g. after a fresh checkout - date resolved: **2026-10-07 10:47**, date raised: 2026-10-07 - **1.12.415** `FIX` `LOW EFF` `resolved by: Claude-JG` linux (#2236) - description: fix wrong initialization for time in renderer on linux systems - **notes:** On Linux the time shown in the renderer starts at zero; confirmed by the maintainer's repeated tests on Ubuntu (2026-10-07) - date resolved: **2026-10-07 10:47**, date raised: 2026-01-26 - **1.12.412** `CHANGE` `NORMAL` `HUGE EFF` `raised by: Claude-JG` `resolved by: Claude-JG` connectors and loads compute their marker values themselves instead of precomputed MarkerData (#2745) - description: The maintainer, 2026-09-29: compute marker values inside the connector (joint, constraint) and load functions, no precomputation of MarkerData; a new temporary data with smaller footprint per marker; check GeneralContact. Migration: a function in CObjectConnector / CLoad that does what the precomputation does today, then each connector and load changed. Advantage: automatic differentiation becomes much simpler. First an evaluation step - what is there now, what are the best options - since it shapes future items and the user elements. revision2026b group RG14. - **notes:** Connectors, joints, constraints and loads compute the values of their markers themselves, through an interface per marker kind, instead of a precomputed MarkerData for every marker; the rigid markers give a homogeneous transformation and the Jacobians follow by automatic differentiation (revision2026b step RG14.2) - date resolved: **2026-10-07 08:32**, date raised: 2026-09-29 - **1.12.375** `DOCU` `raised by: Claude-JG` `resolved by: Claude-JG` PDF: LaTeX macros and backslashes printed as text (#2883) - description: Maintainer 2026-10-07: 'there are a couple of stray \\LU, \\pv, \\mathbf, etc. in the PDF; there are many lost \\ in the PDF, possibly \\ from earlier line breaks'. Found in the text of the PDF: figure references that print the caption (its math stays LaTeX source), a pipe inside math in table rows (the table splits the cell - the rows of the hydraulic actuator, the spring-dampers, the rolling discs), display math not on lines of its own (ANCFThinPlate), LaTeX line breaks and spaces in the Markdown text (trailing backslash, backslash-space, backslash-comma) and backslash-commas in 12 issue texts of the tracker log. - **notes:** The PDF documentation no longer shows LaTeX commands or stray backslashes in its text. - date resolved: **2026-10-07 01:16**, date raised: 2026-10-07 - **1.12.374** `CHECK` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` parameters and output variables that the C++ of an item does not use - found by RG13.3 (#2867) - description: Found by checking the descriptions against the implementation (RG13.3.2-.5); the descriptions say what IS now, the code is for a decision: ObjectContactCurveCircles - the output variables DisplacementLocal, VelocityLocal, ForceLocal are declared and give an empty vector, dynamicFriction and frictionProportionalZone are not used, polynomialData only bends the drawing; ObjectContactCircleCable2D - contactDamping is not used (commented out); ObjectConnectorCoordinateSpringDamperExt - velocityOffset only reaches the user function, the built-in law k(x-x0)+d\*v ignores it; ObjectANCFThinPlate - strainIsRelativeToReference has no effect since the port of RG4.20 (strains always relative to the reference). Options per item: implement, or remove the parameter (no deprecation needed for 1.12-new ones). - **notes:** ObjectContactCurveCircles returns its output variables (gap, gap velocity and contact force per segment) and has friction; ObjectConnectorCoordinateSpringDamperExt uses velocityOffset in its damper force; the parameters contactDamping of ObjectContactCircleCable2D and strainIsRelativeToReference of ObjectANCFThinPlate, which had no effect, are removed. - date resolved: **2026-10-07 01:16**, date raised: 2026-10-06 - **1.12.373** `BUG` `raised by: Claude-JG` `resolved by: Claude-JG` Linux suite of 1.12.372: deprecation warnings on the console, energiesTest (#2882) - description: tmp/Ubuntu/ubuntuTestSuiteConsoleOutput.txt (maintainer, WSL, cp313): 73 DeprecationWarnings on the console. 69 are expected - parameterConversionTest sets every parameter, the deprecated names included, and homogeneousTransformationParameterTest compares rotationMarker0/1 with localHT - and are now kept off the console. 2 came from the mini examples ObjectANCFCable/ObjectANCFCable2D: the mini examples are generated from the miniExample texts in definitions/, so the conversion of \#2873 in python/MiniExamples was undone by the next regeneration; the 11 texts are converted in definitions/. energiesTest.py differs by -5.9e-11 against 3e-11 (rel. 3.3e-12) and goes to UnresolvedOnLinux. - **notes:** The test suite no longer prints the deprecation warnings that its deprecation tests trigger on purpose, and the mini examples of the cable elements use GenerateBeamElementsAlongLine. - date resolved: **2026-10-07 00:03**, date raised: 2026-10-06 - **1.12.372** `CHANGE` `raised by: Claude-JG` `resolved by: Claude-JG` The default drawing size of nodes, markers and sensors is too small to see (#2880) - description: GUI checks on macOS and Ubuntu (K1, 'some markers/sensors are too small to see'): defaultSize = -1 gives a radius of 0.001 \* openGL.advanced.initialMaxSceneSize (1 by default), 1 mm in a scene of 1 m, whatever the size of the scene. Proposal, for decision: relative to the scene the renderer computed (maxSceneSize), e.g. 1 %, or a larger factor. - **notes:** The model of the manual GUI check draws markers and sensors larger and with thicker lines, and the check switches the simplified drawing styles. - date resolved: **2026-10-06 23:36**, date raised: 2026-10-06 - **1.12.371** `EXTENSION` `raised by: Claude-JG` `resolved by: Claude-JG` Shadows of GLSpheres in the OpenGL renderer (#2879) - description: Maintainer, GUIcheckMacOS.txt: the spheres drawn as GLSphere (display lists; graphics.Sphere and, since \#2877, the spheres of connectors and joints) cast no shadow, because each may have many triangles. Proposal: a coarse shadow geometry, e.g. a cylinder or disc per sphere, with some artefacts that are acceptable. - **notes:** Spheres drawn as spheres (graphics.Sphere, the spheres of joints and connectors) cast shadows in the OpenGL renderer. - date resolved: **2026-10-06 23:36**, date raised: 2026-10-06 - **1.12.370** `BUG` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` macOS: abort when a Tk dialog of the SolutionViewer is closed, and when matplotlib shows a window while the renderer runs (#2878) - description: GUIcheckMacOS.txt: (1) closing the SolutionViewer dialog after demo 2 aborts in PyEval\_RestoreThread: the dialog's Tk after-callback calls SC.renderer.DoIdleTasks, whose glfwPollEvents dispatches the Tk close event (one NSApp event loop), so tkinter's PythonCmd runs nested inside a Python callback, with its saved thread state NULL. Proposal for the Mac session: inside a Tk mainloop on macOS, redraw without polling (Tk's loop already delivers the GLFW events), e.g. DoIdleTasks(pollEvents=False). (2) graphicsDataExample.py: plt.show() with the renderer still running aborts in matplotlib's macosx backend (PyEval\_RestoreThread, GIL released); the example now stops the renderer first; whether a GLFW callback touches Python without the GIL is to be checked on the Mac. - **notes:** On macOS, the dialogs of SolutionViewer and AnimateModes no longer let the renderer pump the window events inside their tkinter callbacks, which aborted Python when a dialog was closed; SC.renderer.DoIdleTasks has the argument pollEvents for this. - date resolved: **2026-10-06 23:36**, date raised: 2026-10-06 - **1.12.369** `BUG` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` First manual GUI check on macOS and Ubuntu (1.12.368): the findings that can be fixed without a screen (#2877) - description: From tmp/MacOS/GUIcheckMacOS.txt (maintainer) and tmp/Ubuntu/exudynGuiCheckUbuntu.txt (M. Pieber), 2026-10-06: CTRL+keypad rotation did nothing (R9); F2 showed no message (K10); the selection highlight lasted 0.5 s (R5); sensor traces missing in the raytracer (K7); graphics.Sphere ignored general.sphereTiling (tiling fixed at creation) and the spheres of connectors were triangles with sphereTiling 6 (= 4 segments as display list); contour Displacement: spheres not colored, and bodies without rotation colored by their local position (A3); a failed PNG write was silent; ConvertImages2Video failed with an ffmpeg without libx264 (conda-forge on macOS); the check list and its model: demo 2, which model, V4/V5 on items the settings reach, V14 'store', S5, P1 (plot windows closed at the end of the script), marker/sensor sizes; the docs: ffmpeg on macOS, CTRL+F3 is a macOS system shortcut. - **notes:** Findings of the first manual GUI checks on macOS and Ubuntu: CTRL with the keypad rotates in small steps, F2 shows its message, sensor traces appear in the raytraced image, graphics.Sphere and graphics.Spheres follow visualizationSettings.general.sphereTiling (now 16), the spheres of joints and connectors are drawn smooth, the Displacement contour colors bodies without rotation and spheres correctly, ConvertImages2Video works with an ffmpeg without libx264 (macOS), and a failed image write is reported. - date resolved: **2026-10-06 22:59**, date raised: 2026-10-06 - **1.12.368** `BUG` `raised by: Claude-JG` `resolved by: Claude-JG` macOS: RedrawAndGetImage(useRaytracer=True) segfaults; double free of symbolic vector expressions (#2876) - description: Found by a Claude session on the Mac (tmp/MacOS/mac\_\*.txt, 2026-10-06). (1) Raytracer::SoftwareRenderer always ends by drawing the image into the OpenGL window (DrawImageRGBA), also when RedrawAndGetImage calls it from the Python thread without a current OpenGL context: a no-op on Windows, a NULL dereference in the CGL dispatch on macOS. (2) VectorExpressionSReal::Destroy releases its expressions but keeps the pointers; ~VectorExpressionSReal calls Destroy again after SymbolicRealVector::Destroy did, a double free (heap corruption at MINI EXAMPLE 25, symbolicModuleTest). Both fixes tested on the Mac; raytracerNOGLFWtest.py runs on macOS again. - **notes:** On macOS, SC.renderer.RedrawAndGetImage(useRaytracer=True) crashed, and freeing a symbolic user function that returns a vector corrupted the heap; both are fixed. - date resolved: **2026-10-06 18:06**, date raised: 2026-10-06 - **1.12.367** `TESTING` `raised by: Claude-JG` `resolved by: Claude-JG` The test suite runs the test models in one namespace, which hides a missing name; two models fail when run alone (#2875) - description: runTestSuite.py executes every test model with exec(..., globals()), so a name that a model uses without importing it is found if an earlier model imported it. Found with \#2873: 15 test models and mini examples called GenerateBeamElementsAlongLine without importing it and passed the suite; run alone they stop with NameError. Run alone (pre-run of \#2873), explicitLieGroupIntegratorPythonTest.py fails: SensorNode: OutputVariableType '\_None' is not available in node 0 (line 108); the example reevingSystem.py stops with an InternalError in SolveSteps. Proposal: a fresh namespace per model (a copy of the runner's globals), and the pre-run as a check. - **notes:** The test suite runs each test model and mini example as if it ran alone, in a module of its own, so a missing import is found; restartFileTest passes on Linux. - date resolved: **2026-10-06 17:57**, date raised: 2026-10-06 - **1.12.366** `CHANGE` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` Examples, test models and mini examples use the current item parameters, Create arguments and settings (#2873) - description: The shipped scripts still use deprecated item parameters (physicsMass, rotationMarker0, ...), deprecated arguments of the Create functions (bodyNumbers, bodyNumber, ...) and renamed settings; users copy from them. The scripts are pre-run, the deprecation warnings name file and line, and the names are replaced there; deprecated functions with a different signature (BrickXYZ, GenerateStraightLineANCFCable2D, ...) are listed separately. Maintainer 2026-10-06. - **notes:** The examples, test models and mini examples use no deprecated functions any more: graphics.Brick instead of BrickXYZ, beams.GenerateBeamElementsAlongLine instead of GenerateStraightLineANCFCable(2D) and GenerateStraightBeam, rotationMatrixRef instead of eulerParametersRef. ObjectFFRFreducedOrderInterface works with rotationMatrixRef also for its default rigidBodyNodeType given as string. - date resolved: **2026-10-06 16:49**, date raised: 2026-10-06 - **1.12.365** `BUG` `raised by: Claude-JG` `resolved by: Claude-JG` Linux test suite: the restart file of RK44 is not read back; two new platform differences (#2874) - description: The WSL run of 1.12.363.dev1 (cp310): restartFileTest fails with 'the restart file has a value that is not a number'. The explicit solver never initializes aAlgorithmic, so the restart file holds garbage (subnormal numbers, -nan); std::stod throws out\_of\_range for a subnormal number with glibc, not with MSVC. Fixed: aAlgorithmic set to zero, the restart numbers read with strtod. createSphereQuadContact.py (rel. 1.1e-7, since \#2109) and computeItemTest.py (rel. 2.3e-11) differ on Linux and go to UnresolvedOnLinux. - **notes:** A restart file written by an explicit solver could not be read back on Linux: it contained uninitialized values; they are zero now, and the numbers of a restart file are read the same way on every platform. - date resolved: **2026-10-06 15:34**, date raised: 2026-10-06 - **1.12.364** `BUG` `raised by: Claude-JG` `resolved by: Claude-JG` JointSliding/JointSliding2D: SlidingCoordinate counts the last increment twice after a step (#2872) - description: After a step, PostNewtonStep has added the algebraic increment of the sliding coordinate to the data coordinate, but the algebraic coordinate keeps the increment; the output SlidingCoordinate (data + increment), and DisplacementLocal of JointSliding2D (\#2870), add it a second time. Measured on the setup of SlidingJoint2DTest after 50 steps: data 1.00137056, SlidingCoordinate 1.00142803, increment 5.75e-5; DisplacementLocal shows the increment as tangential drift. The solver itself is not affected: the next Newton solves the increment against the updated data coordinate. Found with RG12.42. - **notes:** The output variable SlidingCoordinate of ObjectJointSliding and ObjectJointSliding2D counted the increment of the last step twice; it is the sliding coordinate of the step. - date resolved: **2026-10-06 15:17**, date raised: 2026-10-06 - **1.12.363** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` joints and connectors: consistent output variables - joint frame, drift and relative frame as HomogeneousTransformation(Local) (#2870) - description: Maintainer 2026-10-06: the connectors and joints have inconsistent output variables; consistent: local drift in joints, joint position/orientation (marker 0), relative position of connectors, DisplacementLocal for items without rotation, a new HomogeneousTransformationLocal for the drift of joints and the marker difference of connectors, HomogeneousTransformation for the joint frame J0 of the classical joints (not the rolling joints). Concept first (RG12.42), table in tmp/connectorOutputVariables.md; nothing implemented before the decisions. - **notes:** Joints and connectors give the same output variables for the same quantity: the new HomogeneousTransformationLocal (the joint frame J1 relative to J0, an exu.HT) for the joints and connectors on rigid markers, HomogeneousTransformation (the joint frame J0) for JointGeneric, JointRevoluteZ, JointPrismaticX and JointPrismatic2D, Position, Velocity and the force for JointRevolute2D and JointPrismatic2D, DisplacementLocal for JointPrismatic2D and JointSliding2D, Displacement for ConnectorRigidBodySpringDamper and ConnectorLinearSpringDamper. - date resolved: **2026-10-06 09:32**, date raised: 2026-10-06 - **1.12.362** `CHANGE` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` settings dialog: the button 'view as code' is 'store model view' and gives SetModelView as CTRL+F3; 'store positions' explains it stores all windows (#2871) - description: Maintainer 2026-10-06: the button should be called 'store model view' and give SC.renderer.Start() and SC.renderer.SetModelView(zoom=..., rotationVector=\[...\], centerPoint=\[...\]) like CTRL+F3; the hints of 'store positions' were misleading: it stores the positions of all windows, not only of the dialog. - **notes:** The visualization settings dialog has a button store model view, which gives SC.renderer.Start() and SC.renderer.SetModelView(zoom, rotationVector, centerPoint) as CTRL+F3 prints it; store positions describes that it stores the positions of all open windows (revision2026b step RG6.10.1) - date resolved: **2026-10-06 08:55**, date raised: 2026-10-06 - **1.12.361** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` macOS: geometricallyExactBeamCurvedTest fails; FMA contraction of clang moves results (#2869) - description: Feedback from the macOS tests (maintainer 2026-10-06): geometricallyExactBeamCurvedTest needs staticSolver.newton.absoluteTolerance = 1e-6, in particular for P=0, which has no load to measure the residual against; -ffp-contract=off reduces the macOS differences from 8 models to 3 and should be the default: arm64 has FMA as baseline and clang/gcc contract a\*b+c by default, MSVC does not. - **notes:** Builds on Linux and macOS no longer fuse a\*b+c into one rounded operation (-ffp-contract=off), as Windows does not, which brings macOS results closer to the reference values; geometricallyExactBeamCurvedTest passes on macOS (revision2026b step RG4.1.4) - date resolved: **2026-10-06 08:55**, date raised: 2026-10-06 - **1.12.360** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev linux: WSL is asked for the repository path through its shell, which eats the backslashes (#2868) - description: exudev linux --py 313 stopped with 'wslpath: C:DATAcppEXUDYN\_git' / 'could not ask WSL for the repository path' (maintainer 2026-10-06): WslRepositoryRoot ran 'wsl wslpath -a C:\\DATA\\...', which current WSL (3.0) passes through the login shell; 'wsl --exec' and forward slashes fix it - **notes:** exudev linux works again on Windows: it asks WSL for the repository path with wsl --exec and forward slashes, which the login shell of current WSL no longer garbles (revision2026b step RG10.17) - date resolved: **2026-10-06 07:56**, date raised: 2026-10-06 - **1.12.359** `DOCU` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` RG13: each item's description is synchronized once with its implementation, and the definition records that it was (#2717) - description: The maintainer, 2026-09-27: each item's description needs to be one-time manually synched with the implementation; then it gets a 'checked' in the definitions file, or a better way for that. Proposal for the better way: the mark records not only who and when, but a fingerprint of the implementation it was checked against - the C++ source of the item (src/Impl\s/C\.cpp and the generated header in src/Autogenerated/) - so that checkDefinitions can report a description whose implementation has changed since it was checked, instead of a checked flag that stays true forever. revision2026b step RG13.3. - **notes:** Every item description - nodes, objects, markers, loads, sensors - is checked once against its implementation and recorded with a fingerprint of the implementation in definitions/descriptionChecks.json; tools/checkDescriptions.py --check (in the all-checks gate) names an item whose implementation changed since, --mark records it again (revision2026b step RG13.3) - date resolved: **2026-10-06 07:12**, date raised: 2026-09-27 - **1.12.358** `TESTING` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a graphics regression suite: several models, several visualization settings (#2582) - description: The drawing code is exercised by exactly one model (\#2562): raytracerNOGLFWtest.py, one set of visualization settings, one checksum. A checksum changes with any visualization change and does not say what changed, so it can only ever be "different" or "equal". What is wanted is a suite over several models and several settings - show/hide of nodes, markers, loads and sensors, different colours and text settings - comparing either low-resolution reference images that a human can also look at, or counts extracted from the graphics data (triangles, lines, texts per item), or both: the counts say WHAT changed, the images say whether it still looks right. Needs the extraction API of the issue filed beside this one. - **notes:** the graphics regression suite: graphics data of every MiniExample, settings variants, user functions, raytracer image (revision2026b step RG2.3) - date resolved: **2026-10-05 23:05**, date raised: 2026-09-22 - **1.12.357** `TESTING` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the drawing code is exercised by exactly one test model (#2562) - description: The UpdateGraphics of every node, object, marker, load and sensor - ~4000 lines of drawing code - is called only by VisualizationSystem when the renderer runs, and every runner sets EXUDYN\_SUPPRESS\_UI\_WINDOW\_OPEN, so no test ever executes one of them. Moving all 79 of them in step R11.4.4 could only be verified by the compiler and by comparing the text of the bodies before and after. What is missing is a headless path that builds the graphics data of a model and checks it - the data is in VisualizationSystemData, so a binding that updates and returns a summary (number of triangles, lines, texts per item) would make the drawing code testable without a window. See revision2026 step R5.18.9. \[2026-09-22, Claude-JG\]: CORRECTION (maintainer, 2026-09-22): the original premise was wrong. python/TestModels/raytracerNOGLFWtest.py runs in the test suite with a reference checksum (runTestSuiteRefSol.py: 0.28151013387134) and calls SC.renderer.RedrawAndGetImage(useRaytracer=True), which goes through MainRenderer::RedrawAndGetImage -\> VSC.UpdateGraphicsDataNow() and VSC.UpdateGraphicsData(), so the UpdateGraphics of every visible item IS executed and its result enters a compared number. What is true is narrower: exactly one model, one set of visualization settings, and a single checksum that changes with any visualization change without saying what changed. The broader work - a graphics regression suite over several models and settings, and the extraction API it needs - is filed separately. - **notes:** the drawing of every item is checked through its graphics data over all MiniExamples and the regression models (revision2026b steps RG2.3, RG2.1) - date resolved: **2026-10-05 23:05**, date raised: 2026-09-20 - **1.12.355** `TESTING` `LOW EFF` `resolved by: Claude-JG` computeInitialAccelerations (#2235) - description: add test for initial accelerations and velocities - **notes:** test model initialAccelerationsTest.py: the initial accelerations of the generalized-alpha method with a constraint and an initial velocity (revision2026b step RG4.19.11) - date resolved: **2026-10-05 23:05**, date raised: 2026-01-23 - **1.12.354** `TESTING` `LOW EFF` `resolved by: Claude-JG` CreateLinearSpringDamper (#1954) - description: add test example - **notes:** test model createLinearSpringDamperTest.py for mbs.CreateLinearSpringDamper (revision2026b step RG12.41) - date resolved: **2026-10-05 23:05**, date raised: 2025-02-05 - **1.12.353** `EXTENSION` `LOW EFF` `resolved by: Claude-JG` CreateLinearSpringDamper (#1953) - description: add create function to MainSystem - **notes:** mbs.CreateLinearSpringDamper: a linear spring-damper along an axis between two rigid bodies or rigid markers, with the arguments of the joints (revision2026b step RG12.41) - date resolved: **2026-10-05 23:05**, date raised: 2025-02-05 - **1.12.351** `CHECK` `LOW EFF` `resolved by: Claude-JG` symbolic (#1740) - description: check examples in Docu for consistency - **notes:** The examples of the symbolic page run: they use esym = exudyn.symbolic, the module functions IfThenElse/SetRecording/GetRecording and Real('name', value) (revision2026b step RG4.19.11) - date resolved: **2026-10-05 23:05**, date raised: 2023-12-19 - **1.12.347** `TESTING` `MEDIUM EFF` `resolved by: Claude-JG` GenericODE2 (#777) - description: add tests for dense and sparse mass and jacobian matrices, together with sparse/dense solvers - **notes:** ObjectGenericODE2 with dense and sparse matrices, with the dense and the sparse solver, gives the same motion: test model genericODE2matrixFormatsTest.py (revision2026b step RG4.19.11) - date resolved: **2026-10-05 23:05**, date raised: 2021-10-09 - **1.12.344** `CHECK` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a MainSystem does not keep its SystemContainer alive (#2851) - description: SC.AddSystem() returns the MainSystem with return\_value\_policy::reference: a script that keeps mbs but drops SC (del SC, or SC created inside a function that returns mbs) works on a system the container has deleted. GetGeneralContact keeps its system alive since \#1512 (reference\_internal); the same for AddSystem/GetSystem would tie mbs to SC. Check what else depends on the current behaviour (SC.Reset, the renderer) before changing it. - **notes:** SC.GetSystem(i) keeps its SystemContainer alive, as SC.AddSystem() does (revision2026b step RG4.19.10) - date resolved: **2026-10-05 18:49**, date raised: 2026-10-05 - **1.12.343** `CHECK` `MEDIUM EFF` `resolved by: Claude-JG` Newton (#1337) - description: C++: check if SysError(s) in CSolverBase::Newton() can be changed into regular failure and step reduction for adaptiveStep - **notes:** With adaptiveStep or automatic step size, a singular system Jacobian is a failed step, which is reduced; a singularity of the model ends the run at the minimum step size with the causing coordinate (revision2026b step RG4.19.4) - date resolved: **2026-10-05 18:49**, date raised: 2022-12-26 - **1.12.342** `CHECK` `MEDIUM EFF` `resolved by: Claude-JG` ContactFrictionCircleCable2D (#1290) - description: shows tangential forces in case of all friction stiffness and damping values are zero; may be caused by specific projection - **notes:** ObjectContactFrictionCircleCable2D without a friction model (frictionStiffness and frictionVelocityPenalty zero) has no tangential force, also when its data node starts in slip (revision2026b step RG4.19.5) - date resolved: **2026-10-05 18:49**, date raised: 2022-11-05 - **1.12.341** `CHECK` `MEDIUM EFF` `resolved by: Claude-JG` CSystem (#692) - description: check JacobianAE: jacobianGM.AddSubmatrixTransposed(temp.localJacobianAE\_ODE2\_t ... if \_t is correctly used - **notes:** The numerical Jacobian of algebraic equations (numericalDifferentiation.forAE) adds for each constraint row only the transposed block the residual has - dC/dq for position-level, dC/dq\_t for velocity-level constraints; the analytic one was right (revision2026b step RG4.19.6) - date resolved: **2026-10-05 18:49**, date raised: 2021-06-28 - **1.12.340** `EXTENSION` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a restart mechanism: how a simulation continues from its restart file (#2850) - description: The maintainer, 2026-10-05: before a restart function is written, evaluate how a restart works together with a model script - where the restart file is injected, for example that the system detects a restart file and loads its state from it. The restart file is written already (simulationSettings.solution.restart); a prototype that reads it is \_InitializeFromRestartFile in basicUtilities.py, not public. Successor of \#1565. - **notes:** A dynamic simulation continues from its restart file: with solution.restart.write the solvers write the state every writePeriod and at the end, and with solution.restart.continueIfAvailable the same script continues from it, appending to the solution and sensor files; results are identical to an uninterrupted run (with modified Newton within the Newton tolerance) (revision2026b step RG12.39) - date resolved: **2026-10-05 18:00**, date raised: 2026-10-05 - **1.12.339** `TESTING` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the PDF documentation is built in no gate (#2856) - description: The maintainer, 2026-10-05: a PDF check in the docs gate. Today exudev docs builds only the html; the PDF (exudev docs --pdf, about 2.5 min) is a release artifact, so a table that runs into the footer, an overfull box, a formula LaTeX cannot set or a missing figure surfaces only when someone reads the PDF. Proposal: exudev docs --pdf --check, run with the gates when the documentation changed, that fails on LaTeX errors and reports overfull boxes and other warnings of the LaTeX log against a baseline. - **notes:** exudev docs --check builds the PDF and fails on a new LaTeX problem against tools/pdfLogBaseline.json - an error, a missing file or character, an undefined reference, a float or box too large for its page, a line much too wide - with its page; part of the docs gate for changes to docs/, definitions/ or conf.py (revision2026b step RG3.36) - date resolved: **2026-10-05 17:30**, date raised: 2026-10-05 - **1.12.338** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev notebooks fails: no --env option (#2865) - description: exudev notebooks stops with AttributeError: 'Namespace' object has no attribute 'env' - the subparser of notebooks has no --env although Notebooks() in commands.py reads options.env and its help names --env venvP313; found in RG12.40, where tools/runNotebooks.py was run directly instead - **notes:** exudev notebooks takes --env (and --py) again; it stopped with an AttributeError without it (revision2026b step RG10.16) - date resolved: **2026-10-05 17:13**, date raised: 2026-10-05 - **1.12.337** `CHANGE` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` Create functions: itemNumbers instead of bodyNumbers and bodyOrNodeList (#2863) - description: The maintainer, 2026-10-05: several Create functions accept bodies, nodes and markers in bodyNumbers, some also bodyOrNodeList; the new interface is itemNumbers=\[None,None\]; bodyNumbers stays, deprecated for 5 years; bodyOrNodeList stays with a DeprecationWarning that names itemNumbers. Affected (to be checked): CreateSpringDamper, CreateCartesianSpringDamper, CreateRigidBodySpringDamper, CreateTorsionalSpringDamper, CreateRevoluteJoint, CreatePrismaticJoint, CreateSphericalJoint, CreateGenericJoint, CreateDistanceConstraint. A proposal for decision first. - **notes:** The Create functions take bodies, nodes or markers in itemNumbers, CreateForce and CreateTorque one item in itemNumber; bodyNumbers and bodyNumber are deprecated until 2031, bodyOrNodeList and bodyList raise a TypeError naming itemNumbers; exudev scripts --fix rewrites them (revision2026b step RG12.40) - date resolved: **2026-10-05 16:10**, date raised: 2026-10-05 - **1.12.336** `CHANGE` `MEDIUM EFF` `resolved by: Claude-JG` CreateCoordinateConstraint (#2337) - description: change bodyNumbers to itemNumbers allowing both bodies and nodes to be constrained - **notes:** CreateCoordinateConstraint takes a body, a node, or None for the ground in itemNumbers; the coordinate of a body is counted over its nodes (revision2026b step RG12.40) - date resolved: **2026-10-05 16:10**, date raised: 2026-04-06 - **1.12.335** `CHANGE` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ANCF thin plate: one sign of curvature and moment, thickness gradients along the node slopes, SurfaceMap, the builder removed (#2864) - description: The maintainer's decisions of 2026-10-05 on RG4.20.4: CurvatureLocal and TorqueLocal with one sign (the negated first component was wrong); ShellMesh projects the global thickness gradient onto the unit node slopes; default integration mode 0 everywhere; the maps as static methods of SurfaceMap without the Map prefix, no aliases; SymSin/SymCos removed (exu.symbolic.sin/cos take floats); ANCFThinPlateBuilder removed without deprecation - it was public only in development versions since 2026-10-05 - and ShellMesh takes a surfaceMap instead. - **notes:** ObjectANCFThinPlate: CurvatureLocal and TorqueLocal with one sign, positive where the surface bends towards its normal; exudyn.shells: ShellMesh(surfaceMap=...) with the maps of SurfaceMap (Cylinder, ConeFrustum, HemisphericalShell, ToroidalPanel, ...), thickness function gradients along the node slopes. - date resolved: **2026-10-05 15:35**, date raised: 2026-10-05 - **1.12.334** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ANCF thin plate visualization of the working copy 2026: normal offset, postprocessed contour, contour layer (#2859) - description: From the same working copy: visualizationSettings.bodies.shells drawNormal, drawNormalFactor, drawNormalColor, drawNormalLines, usePostprocessedContour (node-averaged contour) and contourZeta; finer tiling; the storage of the postprocessed values in VisualizationSystem. Not the setting integrationMode (port note 2). - **notes:** ObjectANCFThinPlate drawing: visualizationSettings.bodies.shells.contourZeta (thickness coordinate of the contour), reducedInterpolation (strain-type contours interpolated bilinearly from the element corners) and drawNormal, drawNormalFactor, drawNormalColor, drawNormalLines (the contour value along the surface normal); bodies.beams.axialTiling quads per direction. - date resolved: **2026-10-05 15:35**, date raised: 2026-10-05 - **1.12.333** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` visualization settings dialog: a button that shows the current model view as code (#2862) - description: The maintainer, 2026-10-05: an additional button in the visualization dialog exports the important parts of the current render state - center point, zoom, model rotation, window size - so that they can be set in the code and the model view is the same on every rerun. - **notes:** The visualization settings dialog has a button 'view as code': it shows and copies the lines that give a script the current model view of the render window - window size, center point, zoom, model rotation - so that every run starts with this view. - date resolved: **2026-10-05 14:37**, date raised: 2026-10-05 - **1.12.332** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` macOS (Apple clang 15): CObjectJointGeneric.cpp does not compile - missing 'template' before GetColumnVector (#2861) - description: Reported 2026-10-05 for 1.12.324.dev1 on arm64 macOS, Python 3.13: in ComputeConstraintEquationsTemplate, A0all is a ConstSizeMatrixBase\, so A0all.GetColumnVector\<3\>(...) needs the template keyword (lines 156, 168, 184, the velocity level written by RG14.2.13 on 2026-10-02). MSVC accepts it, clang does not. - **notes:** macOS (Apple clang): ObjectJointGeneric compiles again; three calls of GetColumnVector on a matrix of the template type had no template keyword. - date resolved: **2026-10-05 10:20**, date raised: 2026-10-05 - **1.12.331** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the settings tables repeat every access path in the name column (#2860) - description: The maintainer, 2026-10-05: a settings item lists its name and each full path (simulationSettings.timeIntegration.newton.numericalDifferentiation.doSystemWideDifferentiation, ...staticSolver...), which makes the tables unreadable online and in the PDF; the paths belong once into the description of the structure, the table names the item only. - **notes:** The tables of the simulation and visualization settings name each item by its name only; the description of each structure says once where it is reached, e.g. simulationSettings.timeIntegration.newton.numericalDifferentiation. - date resolved: **2026-10-05 09:56**, date raised: 2026-10-05 - **1.12.330** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudyn.shells: ANCFThinPlateBuilder, geometry maps and plate helpers of the working copy 2026, ported (#2858) - description: From the same working copy: ShellMesh with stiffness-proportional damping and a thickness function (12 thickness values), exact slopes of the bilinear corner map, ANCFThinPlateBuilder, geometry maps (cylinder, cone, hemisphere, torus, Bezier strip, ...), constraint, edge-load and hinge helpers; names in UpperCamelCase. - **notes:** exudyn.shells (revision by Michael Pieber): ANCFThinPlateBuilder for plate meshes on mapped rectangles, the maps MapCylinder, MapConeFrustum, MapHemisphericalShell, MapToroidalPanel, MapBezierStrip and others, functions for constraints, edge loads and hinges of plate nodes, and ShellMesh with stiffness-proportional damping and a thickness function. - date resolved: **2026-10-05 09:16**, date raised: 2026-10-05 - **1.12.329** `EXTENSION` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectANCFThinPlate: the revision of the working copy 2026 (M. Pieber), ported (#2857) - description: A colleague (Michael Pieber) checked the element against the literature in his working copy and documented the changes in tmp/shells/changesANCFThinPlate2026: material curvature measure, separate membrane and bending integration (modes 0, 1, 2), 12 thickness values and stiffness from the local thickness, Kelvin-Voigt damping, two-pass automatic differentiation of the Jacobian, outputs through the thickness (StrainLocal, StressLocal, ForceLocal, TorqueLocal). Port into the current repository with the renames of 1.12 and the corrections of the port notes. - **notes:** ObjectANCFThinPlate (revision by Michael Pieber): curvatures of the material measure, membrane and bending integrated at separate points (useReducedOrderIntegration 0: Gauss 5x5; 1 and 2: Lobatto 3x3 for the membrane, Gauss 2x2 for the bending), 1, 4 or 12 thickness values with the stiffness from the local thickness, Kelvin-Voigt damping (stiffnessProportionalDamping, bendingStiffnessProportionalDamping) that does not damp rigid motion, and StrainLocal, StressLocal, ForceLocal, TorqueLocal through the thickness; StrainLocal has 6 components, CurvatureLocal is \[-kxx, kyy, kxy\]; test model ANCFThinPlateRevisionTest.py. - date resolved: **2026-10-05 09:16**, date raised: 2026-10-05 - **1.12.328** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the renamed and deprecated item parameters are listed only on each item's page (#2855) - description: The maintainer, 2026-10-05: the settings changes are listed at the end of the settings pages, but where are the item parameter changes listed? Each item page lists its own under the parameter table; a list of all of them, like that of the settings, is missing. - **notes:** The index page of the items reference manual lists every renamed and deprecated item parameter, with a link to its item, as the settings pages list theirs. - date resolved: **2026-10-05 02:07**, date raised: 2026-10-05 - **1.12.327** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectFFRF and ObjectFFRFreducedOrder: the acceleration row of the output variables table is broken over several lines (#2854) - description: A Markdown table row is one line; the formula of the Acceleration row was written over five lines, so the table ended there and the rest of the formula was printed as text after it (the maintainer, 2026-10-05, in the PDF). - **notes:** The acceleration rows of the output variables of ObjectFFRF and ObjectFFRFreducedOrder are one table row again; the rest of the formula was printed as text after the table. - date resolved: **2026-10-05 02:07**, date raised: 2026-10-05 - **1.12.326** `DOCU` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` tables in the PDF: too narrow columns, and tables running into the footer (#2853) - description: The maintainer, 2026-10-05: the notation tables (Symbols in item equations) and the 'Definition of quantities' of ObjectMass1D, ObjectRigidBody, ObjectFFRFreducedOrder, ObjectRotationalMass1D have columns of 20 % of the page; tables longer than the page overlap with the footer (e.g. SolutionFileSettings); the name column of the settings tables is too narrow, their size column mostly empty; headers 'type / function return type' and 'default value' are longer than their content. - **notes:** In the PDF, every table in a section breaks across pages instead of running into the footer, and a table without widths of its own gets them from its content; the settings tables have no size column, short headings (name, type, default) and a wider name column; the item tables say default. - date resolved: **2026-10-05 02:07**, date raised: 2026-10-05 - **1.12.325** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the reference pages name the notebook of an example after every code cell (#2852) - description: The maintainer, 2026-10-05: in the pages of the Python-C++ interface, '(from the notebook ...)' follows every code cell that comes from a notebook; it shall appear once per notebook and page, after its first code cell, smaller and directly under the cell, and only the file name. - **notes:** The pages of the Python-C++ interface name the notebook an example comes from once, after its first code cell on the page, as its file name, small and directly under the cell. - date resolved: **2026-10-05 01:46**, date raised: 2026-10-05 - **1.12.324** `CHECK` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` GeneralContact: the implicit solver keeps a contact only while its force presses, the explicit one while the bodies penetrate (#2848) - description: With contact damping, the active set of the implicit solver (PostNewton) takes a contact only if k\*gap + d\*v\_n \< 0; the explicit solver, and ObjectContactSphereSphere / SphereTriangle / Coordinate in both, take it while gap \< 0, so the damping can pull at the end of a contact. A ball dropped onto a triangle rebounds to 0.1391 implicit against 0.1352 (contactComparisonTest.py). Decision: which of the two is the model, and then make both solvers do it. - **notes:** GeneralContact.keepContactWhilePenetrating = True: a sphere-sphere or sphere-triangle contact acts while the bodies penetrate, and its damping may pull at the end of the contact, as ObjectContactSphereSphere and ObjectContactSphereTriangle do; by default it acts only while its contact force presses (contactComparisonTest.py). - date resolved: **2026-10-05 01:15**, date raised: 2026-10-04 - **1.12.323** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` GeneralContact: a triangle body gets no torque from the normal force of a sphere-triangle contact without friction (#2849) - description: In the sphere-triangle contact of GeneralContact the torque (trigPP - rigid.position) x fVec on the rigid body of the triangles is added only if dryFriction != 0; the normal force at the contact point also has a moment about the body's reference point, so a moving triangle body without friction gets no torque from its contacts. The same condition in the Jacobian. Ground triangles are not affected. - **notes:** GeneralContact: the rigid body of the triangles of a sphere-triangle contact gets the torque of the contact force also without friction, so that linear and angular momentum are conserved; test model generalContactTriangleMomentumTest.py. - date resolved: **2026-10-05 00:59**, date raised: 2026-10-04 - **1.12.322** `CHECK` `HIGH` `MEDIUM EFF` `resolved by: Claude-JG` return value policy (#1512) - description: check return value policy of GeneralContact (as example for further decisions); see if reference in ALL access functions makes no problems if object is deleted on Python side - **notes:** The GeneralContact returned by mbs.AddGeneralContact() and mbs.GetGeneralContact() keeps its MainSystem alive. - date resolved: **2026-10-05 00:44**, date raised: 2023-04-13 - **1.12.321** `CHECK` `LOW EFF` `resolved by: Claude-JG` OutputVariableConnector (#984) - description: check all penalty-based connectors if OutputVariable for forces is only computed if activeConnector=True - **notes:** An inactive RigidBodySpringDamper, LinearSpringDamper and TorsionalSpringDamper (activeConnector=False) reports zero force and torque in its output variables, as the other connectors do; test model inactiveConnectorForceTest.py. - date resolved: **2026-10-05 00:44**, date raised: 2022-03-14 - **1.12.320** `CHECK` `MEDIUM EFF` `resolved by: Claude-JG` allocation failure (#121) - description: assert that every allocation in Matrix, Vector, ResizableArray, ... is performed with try/catch - compare Matrix::AllocateMemory(...) - **notes:** Every allocation of ResizableArray goes through one function that catches a failed allocation and raises an error with the size requested, as Vector and Matrix do. - date resolved: **2026-10-05 00:44**, date raised: 2019-05-13 - **1.12.305** `TESTING` `NORMAL` `MEDIUM EFF` `resolved by: Claude-JG` ANCFBeam (#1500) - description: check for advanced right-angle frame - **notes:** rightAngleFrame.py is the right-angle frame, driven past its buckling point (\#2762); with ObjectANCFBeam the static solver stalls, which is \#2763. - date resolved: **2026-10-04 23:09**, date raised: 2023-04-08 - **1.12.304** `TESTING` `LOW EFF` `resolved by: Claude-JG` ComputeLinearizedSystem (#1395) - description: add test model - **notes:** ComputeLinearizedSystem is tested by mainSystemExtensionsTests.py. - date resolved: **2026-10-04 23:09**, date raised: 2023-01-12 - **1.12.303** `CHECK` `LOW EFF` `resolved by: Claude-JG` ExplicitSolver (#1192) - description: Newton / startOfStep: check if dataCoords should also be copied - **notes:** Checked: all dynamic solvers, the explicit ones included, copy the whole current state - data coordinates included - into the start-of-step state at the beginning of each step. - date resolved: **2026-10-04 23:09**, date raised: 2022-07-10 - **1.12.302** `TESTING` `LOW EFF` `resolved by: Claude-JG` MarkerObjectODE2Coordinates (#613) - description: add simple test into TestModels - **notes:** MarkerObjectODE2Coordinates is tested by coordinateVectorConstraintGenericODE2.py. - date resolved: **2026-10-04 23:09**, date raised: 2021-03-21 - **1.12.301** `CHECK` `MEDIUM EFF` `resolved by: Claude-JG` SlimVector (#390) - description: check if erasing all \ methods in SlimVector work and speed up code performance - **notes:** SlimVector: the copy and move constructors and assignments are the compiler's defaults. - date resolved: **2026-10-04 23:09**, date raised: 2020-05-16 - **1.12.300** `CHECK` `MEDIUM EFF` `resolved by: Claude-JG` mass matrix update (#380) - description: mass matrix is not updated in Generalized Alpha solver in CSolverImplicitSecondOrderTimeInt::ComputeNewtonJacobian - may be critical for 3d rigid bodies - **notes:** Checked: when the mass matrix is not constant, the generalized-alpha solver computes it with every residual, so the Jacobian of a Newton iteration uses the mass matrix of that iterate; the derivative of the mass matrix times the accelerations is not in the Jacobian. - date resolved: **2026-10-04 23:09**, date raised: 2020-05-06 - **1.12.299** `CHECK` `MEDIUM EFF` `resolved by: Claude-JG` contact iteration (#209) - description: make simple example for contact to check changing jacobian matrices from ContactCoordinate - **notes:** contactComparisonTest.py drops a ball with ObjectContactCoordinate, implicit, whose Jacobian changes with the contact state, and compares it with three other contact implementations (\#2749). - date resolved: **2026-10-04 23:09**, date raised: 2019-06-28 - **1.12.298** `CHECK` `LOW EFF` `resolved by: Claude-JG` ConstSizeVector (#124) - description: check if begin/end() overriding of Vector:: function is needed? - **notes:** Checked: ConstSizeVectorBase is not derived from VectorBase and holds its data in an array, so it needs its own begin() and end(); nothing to change. - date resolved: **2026-10-04 23:09**, date raised: 2019-05-13 - **1.12.297** `FIX` `MEDIUM EFF` `resolved by: Claude-JG` GeneralContact (#1947) - description: check difference of friction force computation of SphereSphereContact (see notes in .cpp file) and GeneralContact - **notes:** GeneralContact with an implicit solver keeps the sliding or sticking state of a friction contact that its active set gives during the Newton iteration, as ObjectContactSphereSphere does; a sliding ball agrees with the rigid-body solution (contactComparisonTest.py). - date resolved: **2026-10-04 23:03**, date raised: 2025-02-03 - **1.12.296** `FIX` `HIGH EFF` `resolved by: Claude-JG` GeneralContact (#1848) - description: Test and improve implicit SPHERE-TRIG contact - **notes:** GeneralContact, implicit sphere-triangle contact, agrees with ObjectContactSphereSphere in a drop (contactComparisonTest.py) - to 1e-15 without damping; with damping it releases the ball when the contact force no longer presses (\#2848). - date resolved: **2026-10-04 23:03**, date raised: 2024-06-02 - **1.12.294** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` SetDictionary of the settings takes a dictionary of Exudyn 1.11 (#2847) - description: A dictionary of simulation or visualization settings stored by Exudyn 1.11 (GetDictionary) uses the old names and structures - solutionSettings, linearSolverType, window, openGL.light0position, ...; SetDictionary did not read those keys, and it required every key of the current structures. Revision2026b step RG12.34.7, raised by RG12.34 (\#2813). - **notes:** SimulationSettings.SetDictionary and VisualizationSettings.SetDictionary take a dictionary stored by Exudyn 1.11, with the old names (solutionSettings, linearSolverType, window, ...), and dictionaries with only some keys; keys not given keep their current values. - date resolved: **2026-10-04 21:00**, date raised: 2026-10-04 - **1.12.293** `BUG` `HIGH` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the raytracer can hang in RedrawAndGetImage when tests run in parallel (#2776) - description: Twice on 2026-10-02 the full pytest run (pytest -n 8 python/testing) hung in test\_graphicsRegression.py::testRaytracerImages, in SC.renderer.RedrawAndGetImage(useRaytracer=True) (faulthandler traceback), with all workers idle - a wait, not a loop; a third and fourth run passed, and 8 processes rendering the same images 15 times each in parallel did not hang. The raytracer starts the TaskManager for its ParallelFor (Raytracer::SoftwareRenderer, ExuThreading::EnterTaskManager) unless it is already running; a deadlock there, or a TaskManager left running by a previous test in the same worker, are the candidates. The hung processes stayed and could not be ended from the session. - **notes:** Fixed: a multithreaded solve (parallel.numberOfThreads \> 1) that fails, e.g. because a user function raises, stops its worker threads and closes its files; before, the threads kept running, and a later multithreaded solve, the raytracer, or the end of the Python process could hang. - date resolved: **2026-10-04 20:49**, date raised: 2026-10-02 - **1.12.292** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectContactCurveCircles draws its points with a deprecated setting (#2846) - description: The points of the curve of ObjectContactCurveCircles are drawn with the deprecated visualizationSettings.connectors.contactPointsDefaultSize (0.02); the setting it is deprecated for is contact.contactPointsDefaultSize (0.001), which the other contacts use. Found with revision2026b step RG13.8.2; the maintainer, 2026-10-04: the change is ok. - **notes:** ObjectContactCurveCircles draws the points of its curve with visualizationSettings.contact.contactPointsDefaultSize (default 0.001), as the other contacts, instead of the deprecated connectors.contactPointsDefaultSize. - date resolved: **2026-10-04 20:27**, date raised: 2026-10-04 - **1.12.291** `DOCU` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the documentation says how each item is drawn and which settings it uses (#2840) - description: The maintainer, 2026-10-04: 'the graphics visualization has no docs about how the items are drawn. Which (default) settings are used for tiling, colors, etc. - only available via the code. So, this should be completed and possibly improved if some misleading or inappropriate settings are used in the UpdateGraphics functions. This is mainly for the objects, but also for other items (but they would probably have a generic description for most nodes, markers, etc.).' revision2026b step RG13.8. - **notes:** Every item page of the reference manual has a section Drawing: how the item is drawn, as all items of its kind and beyond, and the visualization settings that act on it, linked. - date resolved: **2026-10-04 19:22**, date raised: 2026-10-04 - **1.12.290** `CHECK` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` Drawing parameters and settings that do nothing or something else than they say (#2843) - description: Found by the inventory of the drawing functions (tools/itemDrawingReport.py, docs/revision/itemDrawingState.md, revision2026b step RG13.8.1): (1) ObjectConnectorDistance.drawSize ('link size') is not read - the connector is a line; (2) ObjectConnectorGravity has show, drawSize ('diameter of spring') and color but no drawing; (3) ObjectConnectorCoordinateVector has show and color but no drawing; (4) 13 more items have show but draw nothing (Node1D, the generic nodes, ObjectGenericODE1, the coordinate markers, LoadCoordinate, SensorLoad, SensorUserFunction); (5) ObjectContactCurveCircles says its circles use circleTiling, the code uses general.cylinderTiling; (6) ObjectANCFThinPlate reads view0.scene.showMeshEdges when it builds its graphics data, a view setting the other items leave to the renderer; (7) a load with a Python user function is drawn with its user function only if general.useMultiThreadedRendering is False, a symbolic one always - nowhere said; (8) the line of a 3D beam without section geometry interpolates its contour colors over 0..L while it runs from -L/2 to L/2; (9) the tiling of connectors and joints mixes general.cylinderTiling, axesTiling, sphereTiling and circleTiling (circleTiling\*4 for the contact circles, 4\*cylinderTiling for rolling discs) without a rule. To decide per finding: draw, remove the parameter, or say what it does. - **notes:** Visualization: connectors.drawSimplified draws springs and ObjectConnectorDistance as lines (default) or as a tube and a rod of drawSize; ObjectConnectorGravity is drawn as a line between its markers if shown, its drawSize is removed; SensorLoad is drawn at the marker of its load; the parameter show of items that draw nothing (Node1D, generic nodes, ObjectGenericODE1, coordinate markers, LoadCoordinate, SensorUserFunction) and show/color of ObjectConnectorCoordinateVector are removed - exudev scripts finds them in a script; ObjectContactCurveCircles draws circles with circleTiling. - date resolved: **2026-10-04 17:51**, date raised: 2026-10-04 - **1.12.289** `IMPROVEMENT` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectKinematicTree computes directly with homogeneous transformations (#2829) - description: The maintainer, 2026-10-04: 'check the main relevant functions in KinematicTree (I suppose ComputeTreeTransformations and ComputeMassMatrixAndODE2LHS); make two local implementations in C++, with a exudyn.experimental switch for the testing. Probably, the evaluations need to be slightly adjusted, as the Featherstone version uses an inverse of the HTs. Most functions like Translation2T66 are just wrappers that did the T66 and the HT path, but with an optimized version just with the HTs, it should be easier to implement and faster. If comparison shows that the new path with HTs works, the old T66 functions could mostly go; probably some 6D motion and force computations will stay - possibly in a more suitable/faster form.' revision2026b step RG16.13.6 to RG16.13.9. - **notes:** ObjectKinematicTree computes its kinematics, mass matrix and forces on the placements of its links (homogeneous transformations); the results agree with the earlier computation to round-off, about 25% faster for small trees. - date resolved: **2026-10-04 17:15**, date raised: 2026-10-04 - **1.12.288** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectKinematicTree.forceUserFunction receives no velocities (#2845) - description: The forceUserFunction(mbs, t, itemNumber, q, q\_t) of ObjectKinematicTree is called with tempVector2 as q\_t, which nothing fills: the function receives an empty list (or a stale one) instead of the joint velocities. No example or test model uses this user function. Found while moving the joint forces into one function for both paths of revision2026b step RG16.13.7. - **notes:** Fixed: the forceUserFunction of ObjectKinematicTree receives the joint velocities q\_t; it received an empty vector. - date resolved: **2026-10-04 16:55**, date raised: 2026-10-04 - **1.12.287** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` The raytracer draws no GraphicsData Circle (#2844) - description: GraphicsData of type 'Circle' (graphics.Circle, and the circles that 2D items draw with AddCircleXY: the 2D joints, contact circles, slope nodes) are drawn by OpenGL but not by the raytracer: Raytracing.cpp converts lines, quadratic lines, triangles, spheres and texts, not glCircles. Found with the GraphicsData example of the user manual as notebook (revision2026b step RG17.5). - **notes:** Fixed: the raytracer draws GraphicsData circles (graphics.Circle) and the circles of 2D items such as joints and contact circles, as lines. - date resolved: **2026-10-04 16:39**, date raised: 2026-10-04 - **1.12.286** `EXTENSION` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` tutorials as Jupyter notebooks: build, test and the first notebook (#2831) - description: The realization of the evaluation of revision2026b step RG17.1 (\#2811): notebooks without stored outputs, rendered by myst-nb in the documentation, run by runTestExamples.py, images of the scene with the raytracer; the first notebook is rigidBodyTutorial3 with exu.HT (RG16.12.5). revision2026b step RG17.2. - **notes:** Done: the tutorials (python/Notebooks/), the examples of the reference manual (python/Notebooks/reference/) and of the user manual pages on graphics, solving and the renderer (python/Notebooks/snippets/) are notebooks with stored outputs; the documentation shows them with what they printed, and the tests run them. - date resolved: **2026-10-04 16:11**, date raised: 2026-10-04 - **1.12.285** `BUG` `HIGH` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` SystemContainer.AppendSystem of a MainSystem that Python owns crashes at the end (#2842) - description: SC.AppendSystem(mbsCopy) with mbsCopy = copy.copy(mbs) - the example 'Copying and referencing C++ objects' of the reference manual - ends in an access violation when SC is deleted or the interpreter exits: AppendMainSystem stores the pointer and MainSystemContainer::Reset() deletes every MainSystem it holds, while the copy made by pickle belongs to its Python object, which deletes it again; deleting mbsCopy before SC leaves a dangling pointer in SC. The same holds for a MainSystem appended to a second container (simulatorCouplingTwoMbs.py). Needs an ownership rule: the container deletes only the systems it created (AddSystem), and AppendSystem keeps the appended one alive (keep\_alive) and unlinks it in Reset. Found by running the examples of the reference manual as notebooks, revision2026b step RG17.4. - **notes:** Fixed: SC.AppendSystem(mbs) with a copy of a system (copy.copy) or the system of another container no longer crashes Python when the container is deleted: the container keeps an appended system alive but does not delete it, and SC.Reset() leaves it to its owner. - date resolved: **2026-10-04 15:51**, date raised: 2026-10-04 - **1.12.284** `IMPROVEMENT` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` curves of connectors drawn with a tiling of their own, as watertight tubes (#2839) - description: The maintainer, 2026-10-04: 'CObjectConnectorReevingSystemSprings: graphics uses nTile = visualizationSettings.general.cylinderTiling, which is wrong; first: the nTiles should depend on the angle; second: it should be a new SC.visualizationSettings.connectors.curveTiling or a similar name, which should also be used by windings resolution in spring-dampers. And we need a function to draw watertight curves along a line, which could be used then both for the reeving system and the spring windings (if drawn in 3D - with a new flag).' revision2026b step RG6.9. - **notes:** Springs and the rope of ObjectConnectorReevingSystemSprings are drawn with visualizationSettings.connectors.curveTiling segments per full turn (the arc of a rope with the share of its angle); connectors.springDraw3D draws the windings of springs as a tube; the rope is one closed tube along its spans and arcs. - date resolved: **2026-10-04 15:20**, date raised: 2026-10-04 - **1.12.283** `FIX` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a 3D beam without section geometry is drawn with a coordinate frame at every tile (#2837) - description: UpdateGraphicsBeam3D (ObjectBeamGeometricallyExact, ObjectANCFBeam) draws a beam without polygonal section geometry as a line - and, marked 'temporary!' in the code, an orthonormal basis of size nodes.basisSize at each of the axialTiling points, also when nodes are not shown. Found with the item images of revision2026b step RG3.31: the default drawing of a beam is a row of arrows. The basis belongs to a setting (or goes), not to every line-drawn beam. - **notes:** Fixed: a 3D beam (ObjectANCFBeam, ObjectBeamGeometricallyExact) without section geometry is drawn as a line; it no longer draws a coordinate frame at every tiling point. The frames are those of its nodes (visualizationSettings.nodes.showBasis). - date resolved: **2026-10-04 15:01**, date raised: 2026-10-04 - **1.12.282** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` SystemContainer.Append is documented, the function is AppendSystem (#2841) - description: The reference manual (pybindSystemContainer.py, the MainSystem introduction and the copy example of the general information) and two error messages of CSystem.cpp and MainSystem.cpp tell to call SC.Append(mbs); the SystemContainer has no Append - its function is AppendSystem (PybindModule.cpp), which simulatorCouplingTwoMbs.py uses. Found by running the examples of the reference manual as notebooks, revision2026b step RG17.4. - **notes:** Fixed: the reference manual (SystemContainer, the MainSystem introduction, the copy example) and the error messages of CSystem.cpp and MainSystem.cpp name SC.AppendSystem(mbs), the function the SystemContainer has. - date resolved: **2026-10-04 14:48**, date raised: 2026-10-04 - **1.12.281** `EXAMPLE` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` examples and test models that show referenceHT, localHT and exu.HT (#2823) - description: The maintainer, 2026-10-04: 'referenceHT, localHT, etc. is rarely used'; 'a couple of examples and test models (like 4+4) should use referenceHT / localHT, just to show how it works and for the tests' - solutionViewerTest.py, rigidBodyTutorial3.py (better as Jupyter tutorial, RG17), and 'a pure prestepuserfunction example showing 4 bodies transformed with the InterpolateSE3/SO3 features, writing the transformations into the renderer (with the solution information string)'. revision2026b step RG16.12. \[2026-10-03, Claude-JG\]: Done 2026-10-04: the example homogeneousTransformationInterpolation.py (RG16.12.1) and solutionViewerTest.py on exu.HT with referenceHT and localHT (RG16.12.2); open: two examples, four test models, rigidBodyTutorial3 as notebook (RG16.12.3 to .5). - **notes:** Done: the notebook tutorialRigidBodyCreate (python/Notebooks/) replaces rigidBodyTutorial3.py; it names referenceHT and shows the frame of a body as exu.HT, together with the examples and test models of revision2026b step RG16.12. - date resolved: **2026-10-04 14:30**, date raised: 2026-10-03 - **1.12.280** `BUG` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` GenerateBeamElementsAlongLine fails without nodeNumberStart and nodeNumberEnd (#2838) - description: beams.GenerateBeamElementsAlongLine, the function that replaces the deprecated GenerateStraightBeam, passed its defaults nodeNumberStart=None and nodeNumberEnd=None to GenerateStraightBeam, which takes -1 for no node: every call without them raised 'failed to convert to NodeIndex, but received None'; it also warned that GenerateStraightBeam is deprecated. Found with the flexible beams tutorial notebook (revision2026b step RG17.2). Now None is passed as -1 and the implementation is called without the warning. - **notes:** beams.GenerateBeamElementsAlongLine works without nodeNumberStart and nodeNumberEnd and no longer warns about the deprecated function it uses. - date resolved: **2026-10-04 13:38**, date raised: 2026-10-04 - **1.12.279** `DOCU` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` representative images for the item pages that lack one (#2830) - description: The maintainer, 2026-10-04: 'I think that most of them are too difficult to do them automatically. Suggestion: check which items (mostly bodies, loads, joints) would make sense to have a representative image - and which ones do not yet have one ... add a couple of images, some maybe from a Testmodel or within 1-2 scripts that are hand-made and which extract the images for the missing cases ... use the non-simplified drawing modes for springs, basis vectors, etc.; extract images with raytracer and try to adjust them yourself.' Replaces RG2.3.3.7, an automatic image per item. revision2026b step RG3.31. - **notes:** 23 item pages show a representative image of the item, drawn by the raytracer: the ground, mass point, planar rigid body, kinematic tree, beams, thin plate, FFRF body, the loads, spring-dampers, distance constraint, reeving system, rolling discs, planar joints, sphere contact and the rigid body marker. - date resolved: **2026-10-04 11:15**, date raised: 2026-10-04 - **1.12.278** `BUG` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` PlotSensor fails for data given as numpy array when an output directory is set (#2836) - description: mbs.PlotSensor(sensorNumbers=\[data\]) with a numpy matrix raised 'The truth value of an array with more than one element is ambiguous' when exudyn.config.outputDirectory is set (EXUDYN\_OUTPUTDIRECTORY, as the runners and the notebook runner do): the array was passed to OutputFilePath as if it were a file name. Found with the first tutorial notebook (revision2026b step RG17.2). Data given as array is now taken as it is. - **notes:** PlotSensor plots data given as numpy array also when an output directory is set (exudyn.config.outputDirectory). - date resolved: **2026-10-04 10:55**, date raised: 2026-10-04 - **1.12.277** `DOCU` `LOW` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the start page of the documentation talks about how the documentation is made (#2835) - description: Feedback of a colleague installing Exudyn, forwarded by the maintainer 2026-10-04: 'The text This page is the table of contents, and it is hand-written ... in index.html reads strange =\> remove.' Root cause: a note for maintainers on a page for readers. Removed there; the information is in the repository layout of docs/dev/README.md. revision2026b step RG3.33. - **notes:** The start page of the documentation no longer explains how the documentation is made. - date resolved: **2026-10-04 10:36**, date raised: 2026-10-04 - **1.12.276** `FIX` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` aligned formulas break in the HTML pages: begin{aligned} ended with end{split} (#2834) - description: Feedback of a colleague installing Exudyn, forwarded by the maintainer 2026-10-04: 'In the html doc, sometimes \\begin{aligned} ended with \\end{split} occurs (e.g. ObjectRigidBody). This should be fixed globally.' Cause: Sphinx splits a display formula at a blank line into separate equations, each wrapped in split, which tears an aligned environment apart; the blank lines came from LaTeX comment lines ('%') inside the formulas of the definitions, which the converter emptied but did not remove (4 item pages), and from blank lines in docs/manual/solver.md (7 formulas). The converter removes such lines; checkMathMacros --check refuses a blank line inside display math. revision2026b step RG3.32. - **notes:** Aligned formulas in the HTML documentation no longer break apart (begin{aligned} ended with end{split}). - date resolved: **2026-10-04 10:36**, date raised: 2026-10-04 - **1.12.275** `FIX` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev env stops at the first environment of the version matrix that a developer does not have (#2833) - description: Feedback of a colleague installing Exudyn, forwarded by the maintainer 2026-10-04: 'exudev env error message: the conda environment venvP310 does not exist. It searches for all packages of the python matrix for a complete build - not required by a developer that does not do the release-runs and tests. Only for a complete build, different venvs for different Python versions shall be required.' Without --py or --env, exudev env now probes the environments that exist and names the missing ones of the matrix as needed only for build --complete. revision2026b step RG10.15. - **notes:** exudev env no longer requires the environments of the whole Python version matrix; they are needed only for exudev build --complete. - date resolved: **2026-10-04 10:36**, date raised: 2026-10-04 - **1.12.274** `FIX` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the test suite fails without matplotlib instead of saying what to install (#2832) - description: Feedback of a colleague installing Exudyn, forwarded by the maintainer 2026-10-04: 'The test-suite needs matplotlib to be installed; otherwise, it fails. Should it be like that?' Measured with matplotlib blocked: 9 test models failed - eight plot (PlotSensor, matplotlib.pyplot) after or instead of computing their result, and allExudynModulesTest failed because exudyn.misc.resultsMonitor imported matplotlib at module level. matplotlib is optional (rule 6), part of the \[tests\] extra. Now: resultsMonitor imports it when it is there and says so when the monitor is started without it; a test model that fails for a missing package of the \[tests\] extra is SKIPPED, listed at the end with 'pip install exudyn\[tests\]', and does not fail the run - unless it computed its result before, then it is judged as usual. revision2026b step RG2.5. - **notes:** The test suite runs without matplotlib and the other packages of the \[tests\] extra: a test model that needs a missing one is skipped and listed with pip install exudyn\[tests\]. - date resolved: **2026-10-04 10:36**, date raised: 2026-10-04 - **1.12.273** `CHANGE` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the unused 6x6 Pluecker matrices of the kinematic tree are removed (#2828) - description: The maintainer, 2026-10-04: 'the kinematic tree uses the C++ HT, it is a typedef in KinematicsBasics.h ... first remove the unused T66 Pluecker transformations (inside \#ifndef USE\_EFFICIENT\_TRANSFORMATION66 ...)'. USE\_EFFICIENT\_TRANSFORMATION66 was always defined, so Transformation66 is HomogeneousTransformation and the 300 lines of Matrix6D implementations were never compiled. revision2026b step RG16.13.5. - **notes:** The unused 6x6 Pluecker matrix implementation of the kinematic tree was removed; the tree computes with homogeneous transformations. - date resolved: **2026-10-04 00:48**, date raised: 2026-10-04 - **1.12.272** `CHANGE` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the robotics classes use exu.HT instead of the 4x4 numpy arrays of rigidBodyUtilities (#2821) - description: The maintainer, 2026-10-04: 'the robotics.Robot class (and the related classes) still use the Python HomogeneousTransformation', and the examples using the Robot class. Robot, RobotLink, RobotBase, RobotTool, the DH conversions, LinkHT/JointHT/COMHT, the inverse kinematics and robotics.models/mobile/special/future work on numpy 4x4 arrays and HTtranslate/HTrotate; a user gives HT=HTtranslate(...). The transition keeps scripts working that give numpy arrays. revision2026b step RG16.10. - **notes:** The robotics classes compute with exu.HT; the HT helpers of rigidBodyUtilities are kept as numpy helpers. - date resolved: **2026-10-04 00:48**, date raised: 2026-10-03 - **1.12.270** `BUG` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` CreateKinematicTree fails when a link with automatic graphics has no offset (#2827) - description: mbs.CreateKinematicTree with automatic graphics (graphicsDataList=None of the parent, or the base graphics) raised UnboundLocalError: gLink, or added the graphics of an earlier link again, when the jointHT of a link has zero translation: the link graphics was created only for a translation of some length, but appended in any case. Found with the measurement of revision2026b step RG16.13.2 (a tree whose first link is at the base). The append moved into the branch that creates it. - **notes:** mbs.CreateKinematicTree with automatic graphics no longer fails for a link whose jointHT has no translation. - date resolved: **2026-10-03 23:23**, date raised: 2026-10-03 - **1.12.269** `IMPROVEMENT` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the functions added to MainSystem have return annotations (#2826) - description: The maintainer, 2026-10-04, choosing option (a) of \#2825: add a step to add return annotations for the Create functions. Since \#2825 the stub assigns the Python functions to MainSystem, so a type checker and an editor take their signature from the functions themselves; the return types that the copied stub had (ObjectIndex, NodeIndex, dict for returnDict=True, ...) must therefore be annotations of the functions: the 25 Create functions and the other functions added to MainSystem (SolveDynamic, SolveStatic, PlotSensor, SolutionViewer, ComputeLinearizedSystem, ...). revision2026b step RG12.38. - **notes:** The functions added to MainSystem (Create functions, solvers, PlotSensor, ...) have return annotations, so that editors and type checkers know what they return. - date resolved: **2026-10-03 23:23**, date raised: 2026-10-03 - **1.12.268** `EXTENSION` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectKinematicTree takes its joints as jointHTs (#2824) - description: The maintainer, 2026-10-04: 'ObjectKinematicTree still has only jointTransformations and jointOffsets, but I believe that jointHTs would be much more convenient and could also boost the internal computations (?). Put there a step in the plan with substeps to suggest a transition to jointHTs, like adapting the CreateKinematicTree function, requiring a HTList (similar to Vector3DList) for the C++ interface, adapting the C++ implementation, also adapting the TreeLink to exudyn.HT'. revision2026b step RG16.13. - **notes:** mbs.CreateKinematicTree passes jointHTs and TreeLink.jointHT is an exu.HT; exu.HT(H) copies an HT; storing the joint HTs in ObjectKinematicTree was measured and brings no gain, so the two lists stay with jointHTs as their view. - date resolved: **2026-10-03 23:23**, date raised: 2026-10-03 - **1.12.267** `IMPROVEMENT` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` go to definition of mbs.CreateRigidBody reaches the Python function, not only the stub (#2825) - description: The maintainer, 2026-10-04: 'The Create... functions are injected into MainSystem, thus the direct navigation to these functions is not possible. If I use spyder or VS Code and I click on CreateRigidBody, it directs me to the .pyi file. Is there a fix for that?' The stub declares each added function as a method of MainSystem with its own copy of the signature and the first sentence of the docstring; the function itself is MainSystemCreateRigidBody in exudyn/misc/mainSystemExtensions.py. revision2026b step RG16.14. \[2026-10-03, Claude-JG\]: The step is revision2026b step RG12.37, not RG16.14 (it is not about the HT). Tried on a copy of the package with jedi 0.20 and mypy: (a) CreateRigidBody = \_MainSystemCreateRigidBody in the stub - mypy types it from the function, jedi's go to definition lands on that stub line and its inference reaches the source; (b) a class-scoped import in the stub - jedi goes straight to the source, mypy refuses it; (c) the stub docstring names the function. Recommended (a) with return annotations on the functions; the maintainer decides after a look in VS Code. - **notes:** Go to definition of mbs.CreateRigidBody and the other functions added to MainSystem reaches the Python function: the stub assigns the function itself, and type checkers take its signature from it. - date resolved: **2026-10-03 22:27**, date raised: 2026-10-03 - **1.12.266** `CHANGE` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` examples and test models use exu.HT instead of the HT functions of rigidBodyUtilities (#2822) - description: The maintainer, 2026-10-04: 'whenever rigidbody transformations are used - in particular with kinematic trees and with more complicated kinematics, the exudyn.HT feature should be used'. 23 examples, 20 test models and the library modules graphics, plot and lieGroupBasics call HomogeneousTransformation, HTtranslate, HTrotateX/Y/Z, HT2translation, HT2rotationMatrix, InverseHT or HT0; a test model whose result shall stay exactly the same is converted only where the numbers do not change. revision2026b step RG16.11. - **notes:** Examples and test models that build the frame of a marker give its localHT with exu.HT. - date resolved: **2026-10-03 22:27**, date raised: 2026-10-03 - **1.12.265** `CHANGE` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the library builds the frames of markers with exu.HT, and the Create functions no longer pass rotationMarker0/1 (#2820) - description: The maintainer, 2026-10-04: 'ObjectJointPrismaticX.py uses localHT, but uses HomogeneousTransformation from rigidBodyUtilities, not the exudyn function =\> check whether other scripts / files in the library use HomogeneousTransformation'; 'robotics.CreateRedundantCoordinateMBS uses rotationMarker; CreateFunctions still use rotationMarker'. Since \#2804 the rotation of a joint is in its markers' localHT, and the Create functions pass a unit rotationMarker0/1 - the deprecated parameter, which a reader of the library takes as the way to do it. The library and the definitions (MiniExamples, the advice of the deprecated rotationMarker parameters) build the localHT with exu.HT. revision2026b step RG16.9. - **notes:** The Create functions and robotics.Robot.CreateRedundantCoordinateMBS give the rotation of a joint to its markers only (localHT built with exu.HT) and no longer pass rotationMarker0/1. - date resolved: **2026-10-03 21:19**, date raised: 2026-10-03 - **1.12.264** `EXTENSION` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exu.HT offers the logarithm and the exponential map on SE(3) and R3xSO(3) (#2819) - description: The maintainer, 2026-10-04: 'exudyn.HT misses the LogSE3/R3xSO3 as well as the according Exp features; they are all in the C++ core and it would be nice to have them directly available.' LogSE3() and LogR3xSO3() give the 6 components \[U, Omega\] of the motion vector, SetExpSE3(v) and SetExpR3xSO3(v) set the HT from it and return it, as the other Set functions do (RG16.6). On EXUlie::LogSE3Vector, ExpSE3 and ExpSO3 of RigidBodyMath.h. revision2026b step RG16.8. - **notes:** exu.HT gives and takes the logarithm and exponential map: LogSE3() and SetExpSE3(v) for the motion vector of a screw motion, LogR3xSO3() and SetExpR3xSO3(v) for the translation and the rotation vector. - date resolved: **2026-10-03 21:19**, date raised: 2026-10-03 - **1.12.263** `FIX` `LOW` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` LoadBinarySolutionFile prints verbose= on every call (#2818) - description: basicUtilities.LoadBinarySolutionFile prints 'verbose=' and the value unconditionally - a debug line left in. Found with binarySolutionFileTest.py (RG12.34). - **notes:** LoadBinarySolutionFile no longer prints verbose= on every call. - date resolved: **2026-10-03 20:55**, date raised: 2026-10-03 - **1.12.262** `IMPROVEMENT` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` mbs.Inspect answers the node types a node marker requests, and Assemble checks them from the declaration (#2817) - description: The node types a node marker requests (Position or Position2D, Orientation or Orientation2D) were checked by hand-written C++ in CSystem::CheckSystemIntegrity and declared separately as requestedNodeTypes in the definitions, for the documentation only; mbs.Inspect did not answer them. Now the declaration generates MainMarker::GetRequestedNodeTypes(), Assemble checks it, and mbs.Inspect(marker, InspectType.RequestedNodeTypes) returns it - per node a list of requirements, each a list of alternatives. revision2026b step RG12.29.2. - **notes:** mbs.Inspect(marker, InspectType.RequestedNodeTypes) answers the node types a node marker requests, as requirements each a list of alternatives; Assemble checks them from the same declaration. - date resolved: **2026-10-03 20:55**, date raised: 2026-10-03 - **1.12.261** `FIX` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the binary solution file takes the size of its numbers from solution.precision (#2816) - description: The binary solution file wrote float or double depending on the console precision (consolePrecision, before 1.13 outputPrecision), while the description of solution.file.binary says solution.precision. The maintainer (2026-10-04): use solution.precision - below 8 float, otherwise double. The examples that set solution.precision = 6 for a float file (ANCFcableCantilevered, ANCFslidingJoint) now get one; no script relied on the console precision for it. Test model binarySolutionFileTest.py. revision2026b step RG12.34. - **notes:** The binary solution file stores float if solution.precision is below 8 and double otherwise, as its description says; before, the console precision decided. - date resolved: **2026-10-03 20:55**, date raised: 2026-10-03 - **1.12.260** `IMPROVEMENT` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` two Newton structures for time integration and static solver, with the modified Newton by default in the time integration (#2815) - description: NewtonSettings is shared; with the forwarding of RG12.1 two structures are possible, most members copied, each with its own defaults - useModifiedNewton=True for the time integration; the test suite has to be evaluated again (maintainer 2026-10-04). - **notes:** The time integration uses the modified Newton method by default: timeIntegration.newton.useModifiedNewton is True, much faster for most models; results change within the Newton tolerances. staticSolver.newton keeps the full Newton method. - date resolved: **2026-10-03 20:55**, date raised: 2026-10-03 - **1.12.259** `CHANGE` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` item parameters renamed as decided in RG12.31: the prefix physics dropped, the friction forces, use... flags (#2814) - description: physicsMass -\> mass and 26 more, sphereRadius, dynamicFrictionForce/staticFrictionOffsetForce/viscousFrictionForce, factor1, rollingViscousFriction, useIntrinsicFormulation, useClassicalFormulation; the old names forward until 2031; C++, library, scripts, documentation and tests follow (maintainer 2026-10-03). - **notes:** the item parameters of bodies and finite elements lost their prefix physics (physicsMass is mass, ...), and sphereRadius, the friction forces of CoordinateSpringDamperExt, factor1, rollingViscousFriction, useIntrinsicFormulation and useClassicalFormulation are renamed; every old name still works with a warning until 2031, and exudev scripts --fix rewrites a script - date resolved: **2026-10-03 18:44**, date raised: 2026-10-03 - **1.12.258** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` settings and item parameters that could be renamed or restructured, for the maintainer's decision (#2802) - description: maintainer 2026-10-03: search simulation settings and item parameter names that could be renamed or restructured; listed as revision2026b step RG12.31 for decision. - **notes:** the settings and item parameters that could be renamed were listed and decided; realized in \#2813 and \#2814 - date resolved: **2026-10-03 18:44**, date raised: 2026-10-03 - **1.12.257** `CHANGE` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` simulationSettings renamed and restructured as decided in RG12.31, with every change the deprecation needs (#2813) - description: No substructure ends in Settings (solution, linearSolver), solution.file/.sensors/.restart, show.\*, timeIntegration.realtime and .solverType, newton.active/.residualMode, camel case fixes; the old names forward until 2031; C++, library, scripts (exudev scripts --fix), documentation and tests follow (maintainer 2026-10-03). - **notes:** the simulation settings are reordered - solution.file, solution.sensors, solution.restart, linearSolver, show, timeIntegration.solverType, explicit and realtime, newton.active and residualMode; every old name still works with a warning until 2031, and exudev scripts --fix rewrites a script to the new names - date resolved: **2026-10-03 18:03**, date raised: 2026-10-03 - **1.12.256** `DOCU` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the flow charts of the documentation as TikZ again: vector graphics in the PDF, images on the web (#2812) - description: The mermaid charts of introduction.md, solver.md and theoryContact.md are of low quality compared to the TikZ figures of the old LaTeX documentation (tmp/oldDocs/theDoc): arrows, colors, fonts, and they did not fit the page. Keep the current content of the charts, draw them in TikZ again: one small standalone .tex per figure, compiled only when a figure changes (an exudev command, needs LaTeX), giving a PDF for the PDF build and an image for the web (maintainer 2026-10-03). - **notes:** the flow charts of the documentation are TikZ again: vector graphics in the PDF and SVG on the web, compiled by exudev figures when a chart changes - date resolved: **2026-10-03 16:38**, date raised: 2026-10-03 - **1.12.255** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exu.HT: the functions of the accepted proposal, with examples in its documentation and tests (#2810) - description: Realization of the HT proposal: the bindings on the existing C++ conversions, examples in the data structures section (rotation, position, the node coordinates), a test model. - **notes:** exu.HT converts from and to Euler parameters, Tait-Bryan angles, rotation vector and the coordinates of the rigid body nodes, gives Relative, InterpolateSO3, InterpolateSE3, RotationAngle and RotationAxis; its Set functions return it - date resolved: **2026-10-03 15:51**, date raised: 2026-10-03 - **1.12.254** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exu.HT as the place for rigid body transformations: a proposal for its functions and names (#2809) - description: The coordinates of the rigid body nodes from and to an HT (position with Euler parameters, Tait-Bryan angles Rxyz or rotation vector), more functions that nodes, markers and items need, and the names of the class (translation or position) - for the maintainer's decision (2026-10-03). - **notes:** decided: exu.HT keeps translation; node coordinates, Relative, InterpolateSO3/SE3, angle and axis, chained Set functions - date resolved: **2026-10-03 15:51**, date raised: 2026-10-03 - **1.12.253** `IMPROVEMENT` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` deprecations of the Python library declared like those of the C++, and a build check for expired ones (#2807) - description: The Python library deprecates functions and arguments by hand - a docstring saying DEPRECATED, an exu.Print('WARNING: ...'), about 20 places (AddRevoluteJoint, bodyList of the Create functions, GeneticOptimization arguments, ...) - with no version, no year of removal and nothing that finds them. Proposal: one declaration with since and expires for every deprecation, the library warning through exudyn.special.deprecations, and a check in exudev generate --all-checks that lists all deprecations and fails for one past its year (maintainer 2026-10-03). - **notes:** the deprecated functions and arguments of the Python library warn once per session at the line of the script and are counted in exudyn.sys\['deprecationUse'\]\['library'\]; every deprecation of Exudyn has a year of removal, and a build check fails once it has come - date resolved: **2026-10-03 15:06**, date raised: 2026-10-03 - **1.12.252** `DOCU` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` Python-C++ command interface: the Exudyn module page in sections, the persisted settings a manual page, the environment variables a page of their own (#2808) - description: The module page had one section with every member; its groups (config, experimental, special and its parts, variables and sys) become sections from the definitions. The settings that persist between runs, with the plot windows of PlotSensor, move to the manual page userSettings.md; the environment variables become the last page of the chapter, after the type definitions (maintainer 2026-10-03). - **notes:** the Exudyn module page has a section per group of members; the settings that persist between runs are a page of the user manual, the environment variables the last page of the Python-C++ command interface - date resolved: **2026-10-03 14:37**, date raised: 2026-10-03 - **1.12.251** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` every use of a deprecated name is recorded in exudyn.sys\['deprecationUse'\] (#2806) - description: Grouped by source - simulationSettings, visualizationSettings, items, functions - with a count per name; always written, a flag in exudyn.special.deprecations turns it off. A test or a user sees whether a script used anything deprecated without catching warnings (maintainer 2026-10-03). - **notes:** every use of a deprecated name is counted in exu.sys\['deprecationUse'\], by source and name; exu.special.deprecations.recordUse = False turns it off - date resolved: **2026-10-03 13:55**, date raised: 2026-10-03 - **1.12.250** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev scripts reports deprecated item parameters (#2805) - description: checkUserScripts reads the deprecated settings and functions from definitions/, but not the deprecated item parameters: the renames of RG12.2 and the deprecated rotationMarker0/1 of the joints and connectors, given as keyword of an item class or as key of an item dictionary. - **notes:** exudev scripts reports deprecated and removed item parameters, as keyword of the item class and as key of an item dictionary - date resolved: **2026-10-03 13:55**, date raised: 2026-10-03 - **1.12.249** `IMPROVEMENT` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` deprecation warnings where the user writes the deprecated name, switched in exudyn.special (#2804) - description: A deprecated item parameter (rotationMarker0/1) warns at Assemble today, so the warning points at mbs.Assemble() and not at the line that wrote it. Proposal: warn in the item class (itemInterface) and in the dictionary path, declared in definitions/, with one switch in exudyn.special for once per session or always (debugging). - **notes:** a deprecated setting, item parameter or function warns once per session and name, at the line of the script that uses it; exu.special.deprecations.warnOnce = False shows every use - date resolved: **2026-10-03 13:55**, date raised: 2026-10-03 - **1.12.248** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectContactCurveCircles: rotationMarker0 removed (#2803) - description: The parameter was never applied to the contact, only to the drawing, and Assemble refused any value other than the unit matrix; the frame of the curve is the frame of marker 0, which takes a rotation as localHT. Removed without deprecation (maintainer 2026-10-03). - **notes:** ObjectContactCurveCircles has no rotationMarker0 any more: it was used only for drawing, and Assemble refused any value other than the unit matrix; the curve lies in the frame of marker 0, which takes a rotation as localHT - date resolved: **2026-10-03 13:06**, date raised: 2026-10-03 - **1.12.247** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectConnectorRigidBodySpringDamper multiplies rotationMarker0 from the wrong side (#2801) - description: found in revision2026b step RG14.2.15: the connector computes A0all = rotationMarker0\*A0, its documentation, CreateRigidBodySpringDamper (MR0 = A0^T R) and all other joints use A0\*rotationMarker0; a rotationMarker0 different from the unit matrix on a rotated marker 0 gave the wrong frame. - **notes:** ObjectConnectorRigidBodySpringDamper applies rotationMarker0 after the frame of marker 0, as the joints do and as documented; models with a rotationMarker0 other than the unit matrix move differently - date resolved: **2026-10-03 11:25**, date raised: 2026-10-03 - **1.12.246** `CHANGE` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` parallel.multithreadedLowerLimit... instead of multithreadedLimit... (#2800) - description: maintainer 2026-10-03, after revision2026b step RG12.1: the double L of multithreadedLLimit... meant lower limit; the settings are multithreadedLowerLimitLoads, ...Residuals, ...Jacobians, ...MassMatrices; the old LLimit names forward until 2031. - **notes:** parallel.multithreadedLowerLimitLoads, ...Residuals, ...Jacobians, ...MassMatrices; the old multithreadedLLimit names forward with a DeprecationWarning until 2031 - date resolved: **2026-10-03 11:25**, date raised: 2026-10-03 - **1.12.245** `EXTENSION` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` item parameters cannot be deprecated (#2589) - description: When an item parameter is renamed there is no path that keeps an old script working: unlike visualizationSettings, the item interfaces have no deprecation mechanism. Wanted (maintainer, 2026-09-22): the same feature for item parameters, either restricted to the classes of itemInterface.py - which is generated, so one place - or extended to the Get/Set functions of the items themselves. If it reaches the C++ side, the deprecated names must be searched LAST, so that the common case pays nothing. - **notes:** An item parameter can be renamed with its old name kept: it is still taken in the item class, in a dictionary and by GetObjectParameter/SetObjectParameter, with a DeprecationWarning naming the new one. - date resolved: **2026-10-03 09:59**, date raised: 2026-09-22 - **1.12.244** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` simulationSettings has no deprecation mechanism (#2588) - description: A member of visualizationSettings can be marked deprecated in the definitions - Deprecated(since, expires) plus the SFDeprecated flag, 93 members carry it today - and a user who sets the old name gets a message that names the new one. simulationSettings uses none of it, although the mechanism is the same generator and the same structure machinery: a renamed solver setting simply disappears. Apply it there. - **notes:** simulationSettings members can be renamed or moved with the old name kept as deprecated, forwarding with a DeprecationWarning; parallel.multithreadedLLimit... are parallel.multithreadedLimit... now. - date resolved: **2026-10-03 09:41**, date raised: 2026-09-22 - **1.12.243** `CHANGE` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` access functions: single functions per access type in the objects, with precise interfaces (#2744) - description: The maintainer, 2026-09-29: GetAccessFunctionBody(AccessFunctionType, localPosition, Matrix& value) serves every access type through one function and a switch, with workarounds (e.g. the vector for JacobianTtimesVector\_q passed in the output matrix). Revise into single functions per access type in the objects, with interfaces that say what they take and return. First: which objects need which access functions and what would be best for them. Then possibly a check that the declared access function flags (ItemAccessFunctionTypes) and the functions a definition declares agree. revision2026b step RG9.3. - **notes:** The access function types of an object are derived from the access functions it provides; AccessFunctionType.SuperElementAlternativeRotationMode is removed, the mode is an argument of the super element access function. - date resolved: **2026-10-03 08:16**, date raised: 2026-09-29 - **1.12.242** `CHECK` `raised by: Claude-JG` `resolved by: Claude-JG` fourteen figure files in docs/figures are referenced by nothing (#2594) - description: Twelve .pdf and two .eps files in docs/figures/ are referenced by no page, no definition and no tool: CommonTangents3D.eps, DrawSystemGraphExample.pdf, RotationAxisAngle.pdf, RotationAxisAngleDerivation.pdf, degrees\_of\_freedom.pdf, elementaryRotationX.pdf, elementaryRotationY.pdf, generalContactANCF2Dcircle.pdf, generalContactSpheres.pdf, open\_closed\_loop.pdf, plotSpringDamper.pdf, spectralRadiusZeta0.pdf, triangleNormal.eps, triangleNormal.pdf. They are the vector originals of the LaTeX era; most have a .png twin that IS used. Copies are in tmp/unusedFigures for the maintainer to look at (that directory is git-ignored, so nothing left version control). What has to be decided: delete them, or keep them as the editable source of the png twins - in which case they belong somewhere that says so. NOTE eleven further .pdf figures ARE referenced, but only inside \\ignoreRST{} blocks in definitions/itemDefsObjects.py, i.e. only by the LaTeX build that no longer exists; the Markdown and the new PDF of revision2026b step RG3.3 use their png twins. - **notes:** The figures of the documentation that have a vector original are shown as vector graphics in the PDF and as png in the HTML. - date resolved: **2026-10-03 08:16**, date raised: 2026-09-22 - **1.12.241** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exu.HT where a 4x4 numpy HT is taken: rigidBodyUtilities and the robotics classes (#2799) - description: revision2026b step RG16.4.2: exu.HT converts to a 4x4 numpy array (\_\_array\_\_), the HT functions of rigidBodyUtilities and the robotics classes (RobotLink, RobotTool, RobotBase, InverseKinematicsNumerical) take an exu.HT as well; CreateKinematicTree gives jointHTs. - **notes:** numpy reads an exu.HT as its 4x4 matrix (np.array(H)); the HT functions of rigidBodyUtilities and the robotics classes take an exu.HT where they take a 4x4 array. - date resolved: **2026-10-03 07:56**, date raised: 2026-10-03 - **1.12.240** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectKinematicTree takes jointHTs, the joint transformations and offsets as one list of HTs (#2798) - description: revision2026b step RG16.4.1 (named in RG16.2): jointHTs, a list of homogeneous transformations (4x4, 16 values or exu.HT), reads and writes the stored jointTransformations and jointOffsets; None for not given, both given must agree; a list of HTs in the generator. - **notes:** ObjectKinematicTree takes its joint transformations and offsets as one list jointHTs of homogeneous transformations (4x4 matrices, their 16 values or exu.HT). - date resolved: **2026-10-03 07:56**, date raised: 2026-10-03 - **1.12.238** `CHECK` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` homogeneous transformations in the user interface of the rigid items: evaluation (#2781) - description: Evaluate whether ObjectRigidBody, ObjectGround, rigid body nodes and rigid markers can take an HT instead of position and rotation (compatibility mode with None defaults, or a global/auto-detected mode flag), exporting both; localHT in the rigid markers and its deprecation path; homogenize with the localHT work (RG14.2.15); proposal and decisions for the maintainer. - **notes:** Homogeneous transformations in the user interface: ObjectGround referenceHT, CreateGround/CreateRigidBody referenceHT and initialHT, localHT of the rigid markers - None for not given, an HT and its parts must agree. - date resolved: **2026-10-03 01:43**, date raised: 2026-10-02 - **1.12.236** `EXTENSION` `MEDIUM EFF` `resolved by: Claude-JG` OutputVariable (#2202) - description: add kinetic and potential energy - **notes:** Kinetic and potential energy are output variables of the bodies, beams, plates, superelements and spring-dampers (OutputVariableType.KineticEnergy, PotentialEnergy), and exudyn.advancedUtilities.SystemEnergy sums them for a system. - date resolved: **2026-10-03 01:43**, date raised: 2026-01-07 - **1.12.235** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a symbolic user function could not be created for an item whose signature an earlier item has (#2797) - description: found in revision2026b step RG12.4.7: the generated SetUserFunctionFromDict of PySymbolicUserFunctionSet.h had a branch only for the first user function of each signature - CreateSymbolicUserFunction for ObjectConnectorCoordinateSpringDamper (the signature of ObjectConnectorSpringDamper), LoadTorqueVector, LoadMassProportional, MainSystem postStepUserFunction and others raised 'invalid user object type'; 16 of 28 had a branch. - **notes:** CreateSymbolicUserFunction works for every user function, also for items whose signature an earlier item has (ObjectConnectorCoordinateSpringDamper, LoadTorqueVector, LoadMassProportional, the MainSystem's postStepUserFunction, ...). - date resolved: **2026-10-03 01:40**, date raised: 2026-10-03 - **1.12.234** `CHANGE` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the TPyFunction group types leave the definitions: a user function's signature is that of its def (#2796) - description: revision2026b step RG12.4.7 (maintainer 2025-09-25): the 24 group names of definitionTypes.userFunctionSignatures were a lookup key stated next to the def; checked first that the std::function derived from each def's annotations equals the group's for all 34 user functions (RG12.4.7.1), then the type= removed: ItemDefinition gives each user function the type PyFunction\\ with the std::function of its def, the documentation shows the Protocol name, the symbolic set has one member per signature named after its first user function. - **notes:** A user function of an item takes its C++ signature from its def in the definitions; the reference manual shows the name of its Protocol as its type. - date resolved: **2026-10-03 01:40**, date raised: 2026-10-03 - **1.12.233** `EXTENSION` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` GraphicsData gets a Sphere and a CurvedTriangleList (#2709) - description: The maintainer, 2026-09-27: GraphicsData will be extended by two classes, Sphere and CurvedTriangleList. Bigger than it sounds: the GraphicsData dictionary, the OpenGL renderer and the raytracer have to be adapted (at least with temporary workarounds), the pybind interfaces, SC.renderer.GetGraphicsData(), the documentation - so even the minimal implementation takes time. Known limitation to resolve with it: the OpenGL renderer already treats spheres separately for nodes (large node numbers); the raytracer does not draw glSpheres at all, while GetGraphicsData() does return them. The graphics regression test (RG2.3.3, \#2704) is extended when this lands. revision2026b step RG6.7. - **notes:** 6-node triangles are split per edge by its own curvature, so a surface curved in one direction is not split along the other; LinkedCylinders and the hollow Sphere consist of 6-node triangles; Tet10 surfaces of FEMinterface are drawn curved; OpenGL keeps the split while the graphics and the settings do not change. - date resolved: **2026-10-03 01:24**, date raised: 2026-09-27 - **1.12.232** `EXTENSION` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the rigid body markers take localHT, a frame with position and rotation (#2795) - description: revision2026b step RG16.3.3 (decided in RG16.2, \#2781; RG14.2.15, RG16.5): MarkerBodyRigid, MarkerNodeRigid, MarkerKinematicTreeRigid and MarkerSuperElementRigid (localHT replaces offset and adds a rotation) get localHT; the marker frame is the body or node frame times localHT; None for not given. - **notes:** The rigid markers take localHT, a frame with a rotation in the body, link or node: MarkerBodyRigid and MarkerKinematicTreeRigid (localPosition is its translation), MarkerSuperElementRigid (offset is its translation) and MarkerNodeRigid (a rotation only); a joint can take its axis from its markers instead of rotationMarker0/1. - date resolved: **2026-10-03 00:44**, date raised: 2026-10-03 - **1.12.231** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` CreateRigidBody and CreateGround take referenceHT and initialHT (#2794) - description: revision2026b step RG16.3.2 (decided in RG16.2, \#2781): referenceHT next to referencePosition/referenceRotationMatrix, initialHT (the transformation added to the reference) next to initialDisplacement/initialRotationMatrix; None for not given, both raises. - **notes:** CreateGround takes referenceHT, CreateRigidBody referenceHT and initialHT for the reference and the initial position and rotation matrix. - date resolved: **2026-10-03 00:26**, date raised: 2026-10-03 - **1.12.230** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectGround stores its frame as HT; referenceHT next to referencePosition and referenceRotation (#2793) - description: revision2026b step RG16.3.1 (decided in RG16.2, \#2781): ObjectGround stores one HomogeneousTransformation; the parameters referencePosition, referenceRotation and the new referenceHT (a 4x4 array, its 16 values or an exu.HT) are views of it, None for not given; the HT and a part given together must agree. The generator gets the HT parameter with its parts, for the rigid markers to follow. - **notes:** ObjectGround stores its frame as one homogeneous transformation: referenceHT (a 4x4 matrix, its 16 values or an exu.HT) next to referencePosition and referenceRotation, None meaning not given. - date resolved: **2026-10-03 00:26**, date raised: 2026-10-03 - **1.12.229** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exu.HT from 16 values (#2792) - description: Maintainer 2026-10-02: exu.HT also takes the 16 values of the 4x4 matrix row by row - as a sensor stores the output variable HomogeneousTransformation - instead of exu.HT(values.reshape(4,4)). - **notes:** exu.HT also takes the 16 values of a 4x4 matrix row by row, as a sensor of the output variable HomogeneousTransformation stores them. - date resolved: **2026-10-03 00:02**, date raised: 2026-10-02 - **1.12.228** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the frame of a rigid marker in the visualization: markers.showBasis, markers.basisSize (#2791) - description: Maintainer 2026-10-02: rigid body markers get an own rotation (localHT, RG16.3.3), so visualizationSettings.markers gets showBasis and basisSize (the names of nodes); a rigid marker draws its frame: simplified as 3 RGB lines, otherwise 3 arrows as the node basis, with heads 50 % shorter to tell them from a node basis. - **notes:** visualizationSettings.markers.showBasis and basisSize draw the frame of markers with position and orientation: three RGB lines with drawSimplified, else three arrows with short heads. - date resolved: **2026-10-03 00:02**, date raised: 2026-10-02 - **1.12.227** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a system without coordinates is solved (#2790) - description: Maintainer 2026-10-02: allow a zero-sized system (nODE2 = nODE1 = 0) at least in explicit integration, and check where it would break. The solvers refused it in InitializeSolverPreChecks ('cannot solve for system size = 0'); without that check the explicit, implicit and static solvers run with the dense linear solver; the sparse solvers crash for a system of size 0, and the error estimate of the automatic step size control divided by the number of coordinates (ODE23, DOPRI5). - **notes:** A system without coordinates (no ODE2, ODE1 or algebraic coordinates) is solved by the explicit, implicit and static solvers; time, user functions and sensors advance. - date resolved: **2026-10-03 00:02**, date raised: 2026-10-02 - **1.12.225** `CHANGE` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the output variable HomogeneousTransformation as exu.HT (#2789) - description: Maintainer 2026-10-02: GetNodeOutput, GetObjectOutputBody, GetObjectOutput, GetMarkerOutput and GetObjectOutputSuperElement return an exu.HT for OutputVariableType.HomogeneousTransformation instead of 16 numbers - the standard way; sensors keep storing the 16 numbers row by row (a sensor stores rows of numbers), from which exu.HT(values.reshape(4,4)) makes the HT. - **notes:** GetNodeOutput, GetObjectOutputBody and GetMarkerOutput return the output variable HomogeneousTransformation as an exu.HT; a sensor stores its 16 values row by row. - date resolved: **2026-10-02 23:33**, date raised: 2026-10-02 - **1.12.224** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectANCFBeam: the output variable RotationMatrix returns the potential energy (#2788) - description: The case RotationMatrix of CObjectANCFBeam::GetOutputVariableBody has no break and falls through to PotentialEnergy (added with \#2202), so GetObjectOutputBody(beam, RotationMatrix) and a SensorBody return a scalar; found by the output variable HomogeneousTransformation (\#2780), which reads RotationMatrix. - **notes:** The output variable RotationMatrix of ObjectANCFBeam returned the potential energy; it returns the rotation matrix again. - date resolved: **2026-10-02 22:38**, date raised: 2026-10-02 - **1.12.223** `CHECK` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` raytracer: single bright pixels on curved triangles at coarse tiling (#2787) - description: Seen in the images of RG6.7.7.7 (2026-10-02): at nTiles 32 and below, a SolidOfRevolution and a half sphere through the raytracer (160 x 160 pixels) show a few single white pixels on the surface, not at 64 - rays passing between neighbouring curved triangles, or between the flat triangles the raytracer splits them into. To check: watertightness of the split of 6-node triangles along shared edges (the same subdivision on both sides). - **notes:** Curved surfaces (6-node triangles) no longer show single bright pixels in the raytracer: the triangles of one item are split at the same points along shared edges. - date resolved: **2026-10-02 22:38**, date raised: 2026-10-02 - **1.12.222** `IMPROVEMENT` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` homogeneous transformations: the C++ class and its Python binding (#2780) - description: HomogeneousTransformationBase into its own file, out of exulie; 12 numbers stored; fast H\*v, H^-1, H1\*H2, set/get with fixed-size loops and a no-rotation flag (global constexpr switch); tests and measurement; pybind exudyn.HT with operators; note in rigidBodyUtilities.HomogeneousTransformation; HT inside the rigid items and as output variable. - **notes:** exudyn.HT is the homogeneous transformation of the C++ core (composition, inverse, transformed points, 4x4 matrix); every node, body point, marker and connector with Position and RotationMatrix gives the output variable HomogeneousTransformation (16 values, the 4x4 matrix row by row). - date resolved: **2026-10-02 22:38**, date raised: 2026-10-02 - **1.12.221** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectALEANCFCable2D: a connector or load through a body marker fails with a size mismatch (#2786) - description: Since the legacy path is gone (RG14.2.13, \#2745), connectors and loads act through the marker functions, which size the generalized force by the body's 9 coordinates; the position and rotation Jacobians of ObjectALEANCFCable2D have 8 columns (the ANCF coordinates) - 'MultMatrixTransposedVectorAddTemplate: Size mismatch' in the first step (the three CND2022 ALE examples). Fix: the Jacobians get the ALE coordinate as 9th column, zero, which is what the legacy path did implicitly; whether it should be nonzero is \#2784. - **notes:** Connectors and loads acting through a body marker on ObjectALEANCFCable2D work again; they failed with a size mismatch in the first step. - date resolved: **2026-10-02 21:32**, date raised: 2026-10-02 - **1.12.220** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` MarkerSuperElementRigid on ObjectFFRF is accepted by Assemble() and fails in the first evaluation (#2785) - description: Found by test\_accessFunctionsAllBodies.py (RG9.5.6): GetAccessFunctionSuperElement raises 'AngularVelocity\_qt, only possible for ObjectGenericODE2 and ObjectFFRFreducedOrder' when the Jacobian of a MarkerSuperElementRigid on an ObjectFFRF is formed - at the first Newton iteration, not at Assemble(). The consistency check of the marker (or the declared access functions of ObjectFFRF) should refuse it with that reason. - **notes:** Assemble() refuses a connector or load acting through a MarkerSuperElementRigid on ObjectFFRF, which has no rotation Jacobian; before, the simulation failed in its first step. - date resolved: **2026-10-02 20:47**, date raised: 2026-10-02 - **1.12.219** `EXTENSION` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` mbs.ItemCompute: the ODE2 Jacobian of an object, and the bodies not yet in the test of the access functions (#2782) - description: What mbs.ItemCompute (\#2779) does not compute yet: the ODE2 Jacobian of an object or connector (analytic where it has one, else numerical as the solver does), IsValidLocalPosition of a body, the Jacobians of a node with algebraic equations; and the bodies test\_accessFunctionsAllBodies.py does not build yet: ObjectFFRF, ObjectFFRFreducedOrder, ObjectKinematicTree, ObjectALEANCFCable2D, ObjectGenericODE2, the derivative of the Lie group node by composed increments. - **notes:** mbs.ComputeItem computes the analytic ODE2 Jacobian of a body or connector (ComputeItemType.JacobianODE2, JacobianODE2\_t); for superelements and kinematic trees it computes through their markers. - date resolved: **2026-10-02 20:47**, date raised: 2026-10-02 - **1.12.218** `CHANGE` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` mbs.ItemCompute renamed mbs.ComputeItem (#2783) - description: Maintainer's review of RG9.5.1 (2026-10-02): the function is mbs.ComputeItem and its enumeration exu.ComputeItemType, verb first like mbs.AddObject; the rest of the proposal stays (helper in exudyn.advancedUtilities, what=None lists what applies, one vector argument). - **notes:** mbs.ItemCompute and exu.ItemComputeType, new in this release, are named mbs.ComputeItem and exu.ComputeItemType. - date resolved: **2026-10-02 19:49**, date raised: 2026-10-02 - **1.12.217** `IMPROVEMENT` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` mbs.ItemCompute: the computation functions of an item from Python (#2779) - description: Python reaches an item's computation only through output variables. A general access at the current state - mbs.ItemCompute(itemIndex, what, \[optional parameters\]), like mbs.Inspect - to the access functions of bodies, ComputeODE2LHS and mass matrix, constraint equations and Jacobians, connector forces, node and marker Jacobians; functions defined once in base classes; plus a numerical-derivative helper for comparisons. For tests (\#2777), debugging and user items. - **notes:** mbs.ItemCompute(item, what) computes what the solver computes for one object, node or marker at the current state - Jacobians, mass matrix, right-hand side, connector forces, constraint equations and Jacobians, reaction forces, marker kinematics; mbs.ItemCompute(item) lists what applies; exudyn.advancedUtilities.NumericalJacobian gives the numerical derivative to compare with. - date resolved: **2026-10-02 18:27**, date raised: 2026-10-02 - **1.12.216** `TESTING` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` every body's access functions against finite differences (#2777) - description: A pytest that builds each body type with nontrivial (deformed, rotated) coordinates and checks, at several local positions, GetPositionJacobian and GetRotationJacobian against finite differences of the position and rotation matrix (via the output variables), and GetJacobianTransposedTimesVectorDerivative against the numerical derivative of J^T f. Two bugs of this kind were found by chance on 2026-10-02 (ObjectANCFBeam position Jacobian 3 x 8 for 18 coordinates; the rotation Jacobian of NodePointSlope23 not the derivative of its rotation, \#2763). - **notes:** A test checks the position and rotation Jacobians and their derivatives of 15 body types against finite differences; ObjectBeamGeometricallyExact now computes the derivative of its rotation Jacobian times a torque, so torques and joints with rotations on these beams give a consistent Newton Jacobian. - date resolved: **2026-10-02 18:26**, date raised: 2026-10-02 - **1.12.215** `IMPROVEMENT` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a sensor allocates its value vector per evaluation (#2778) - description: CSensor::GetSensorValues fills a Vector per call; with TemporaryMarkerDataStructure (\#2745) this is the remaining allocation of a sensor evaluation (measured 2026-10-02: 4 M allocations for 200 SensorObject over 20000 steps, one per evaluation). A ResizableVector kept per sensor, or the value written into the storage directly. - **notes:** Output variables of coordinate connectors, joints and contacts no longer allocate memory per evaluation, which makes sensors on them faster. - date resolved: **2026-10-02 17:17**, date raised: 2026-10-02 - **1.12.214** `CHECK` `LOW EFF` `resolved by: Claude-JG` PostNewtonStep (#241) - description: Check why markerData is computed with computeJacobian=true in CSystem::PostNewtonStep; is jacobian information really needed? - **notes:** The discontinuous iteration (PostNewtonStep) of contacts and connectors no longer computes the Jacobians of their markers, which it never used. - date resolved: **2026-10-02 13:26**, date raised: 2019-08-22 - **1.12.213** `EXTENSION` `LOW` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` access functions: the position Jacobian of ObjectRotationalMass1D off its axis, a rotation Jacobian of ObjectANCFBeam (#2775) - description: Two access functions a body could provide but does not, each needing a decision: ObjectRotationalMass1D defines its position at any local position but its position Jacobian only on the axis (Assemble refuses connector and load markers elsewhere, \#2744); off the axis it would depend on the rotation angle, as ObjectRigidBody2D does it. ObjectANCFBeam declares no AngularVelocity\_qt, so a MarkerBodyRigid cannot be attached; a rotation could be defined from its slope vectors (which ones, and with which orthogonalization, is the decision). Found in the evaluation of \#2744 (RG9.3.1) and listed in \#2773. - **notes:** ObjectRotationalMass1D accepts connectors and loads at any point of the table, not only on its axis; ObjectANCFBeam accepts MarkerBodyRigid, so torques and joints with rotations act on it; a position marker on ObjectANCFBeam used in a connector no longer fails with 'request of invalid column'. - date resolved: **2026-10-02 12:47**, date raised: 2026-10-02 - **1.12.212** `FIX` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` access functions: the leftovers found in the evaluation RG9.3.1 and the split RG9.3.4 (#2773) - description: Found on the way and left alone, one step at a time: (1) CSystem::CheckSystemIntegrity reports the marker index as the object number when a body lacks the rotation access function, and spells orienation; (2) dead code: the if (false) branch of CObjectANCFCable2DBase::GetPositionJacobian (the exact derivative of the normal, equal to the simpler version in use; ObjectALEANCFCable2D uses the exact one), the commented-out calls of GetAccessFunctionBody in the relative coordinate markers, CObjectRigidBody and VisualizationObject.h, the incomplete commented-out block in CObjectFFRFreducedOrder::GetMassWeightedPositionJacobian, the double SetAll in CObjectANCFBeam::GetMassWeightedPositionJacobian; (3) CMarkerKinematicTreeRigid::ComputeMarkerDataJacobianDerivative raises unconditionally and the code after it is unreachable (the tree declares no JacobianTtimesVector\_q); (4) ideas, not bugs: ObjectRotationalMass1D could provide the position Jacobian off its axis as ObjectRigidBody2D does, ObjectANCFBeam a rotation Jacobian from its slopes. The three findings of section 7 of the evaluation are done in RG9.3.4.2. - **notes:** Fixed the leftovers of the access functions: the message of the integrity check named the marker index as the object number; dead and commented-out code of the split removed; the unreachable code of MarkerKinematicTreeRigid::ComputeMarkerDataJacobianDerivative removed. The two extensions that need a decision are \#2775. - date resolved: **2026-10-02 12:03**, date raised: 2026-10-02 - **1.12.211** `BUG` `HIGH` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectANCFCable2D: the position Jacobian at a point off the axis leaves its third row uninitialized (#2774) - description: GetPositionJacobian (formerly the TranslationalVelocity\_qt case of GetAccessFunctionBody) of ObjectANCFCable2D and ObjectANCFCable2D-based elements sets rows 0 and 1 for localPosition\[1\] != 0 but never row 2, which keeps whatever the matrix held; a MarkerBodyPosition at y != 0 on a cable then projects forces with garbage z-components and the implicit solver can report a singular Jacobian at random. Found by the comparison of the access functions by automatic differentiation (RG9.3.5): a cable on an elastic foundation with markers at y = 0.01 failed or passed depending on the memory. - **notes:** ObjectANCFCable2D and ObjectALEANCFCable2D: the position Jacobian at a point off the axis sets its third row to zero; before, it kept whatever the matrix held, which gave forces with random z-components and could make the implicit solver report a singular Jacobian - date resolved: **2026-10-02 08:51**, date raised: 2026-10-02 - **1.12.210** `BUG` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` graphics.MergeTriangleLists: the edges of g2 are not offset when g1 has no edges (#2769) - description: MergeTriangleLists appends the points of g2 after those of g1, but adds the offset nPoints to the edge indices of g2 only if g1 has edges as well; if g1 has none, the edges of g2 point to the points of g1. Found during revision2026b step RG6.7.7.5 (\#2709), whose edges3 merge offsets always. - **notes:** graphics.MergeTriangleLists: the edges of the second list are offset by the points of the first also when the first has no edges - date resolved: **2026-10-02 01:22**, date raised: 2026-10-01 - **1.12.209** `CHECK` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` computeMassMatrixInversePerBody does not reduce cost unless a sparse solver is also selected (#2400) - description: the flag is documented as computing the inverse of the mass matrix per body so that explicit integration does not need a global solve; and it is the intended answer to the O(N^2) cost of issue 2398 (it cannot be the default; because it gives wrong results when bodies share nodes - a beam or an FEM body - as its own documentation and the maintainer both state). Measured 2026-09-12 on a chain of independent point masses; with the flag value read back from the settings to confirm it was applied: with the DEFAULT DENSE solver the flag changes nothing. At nMasses=1000 and 200 steps: ExplicitEuler 8.43 s off against 8.57 s on, RK44 20.5 against 20.4, DOPRI5 33.0 against 32.7 - all within noise. Selecting EigenSparse is what removes the cost (0.070 s); and only then is the flag worth a further 10 to 15 percent (0.058 s). So on its own the flag does not do what it promises; the user still has to know to change the linear solver. Either the flag should bypass the solver path; or its documentation should say that it must be combined with a sparse solver. Found while building the large system performance test for revision2026 step R2.10 - **notes:** explicitIntegration.computeMassMatrixInversePerBody: documented that it needs a sparse solver (EigenSparse) to reduce the cost of a step - date resolved: **2026-10-02 01:22**, date raised: 2026-09-12 - **1.12.208** `BUG` `NORMAL` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` explicit integration costs O(N^2) per step with the default dense linear solver (#2398) - description: measured 2026-09-12 on a chain of point masses coupled by coordinate spring dampers; explicit Euler; 200 steps: nMasses 250/500/1000/2000 gives 2.5/10.1/42/168 ms per step - the per step cost quadruples on every doubling; so it is O(N^2) although an explicit step on a chain should be O(N). Setting simulationSettings.linearSolverType to EigenSparse makes it linear and 400 times faster at nMasses=2000 (0.084 s against 33.5 s for 200 steps). The dense default is reasonable for small systems; but nothing warns at large N and explicit integration does not obviously need a linear solver at all; so the trap is invisible. Found while building a large system performance test for revision2026 step R2.10 - **notes:** explicit integration with the dense default solver: the warning above 1000 unknowns says that every step costs O(n^2) and names exu.LinearSolverType.EigenSparse; documented in the manual (performance) - date resolved: **2026-10-02 01:22**, date raised: 2026-09-12 - **1.12.207** `BUG` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectJointGeneric: the Jacobian ignores alternativeConstraints (#2772) - description: With alternativeConstraints=True and all rotations constrained, ComputeAlgebraicEquations uses the alternative equations (vx0\*(vy1 x vz0) - 1, ...), but ComputeJacobianAE always forms the Jacobian of the default ones (vz0\*vy1, ...). Newton then works with a wrong Jacobian. Found by revision2026b step RG14.2.9.3 (\#2745): the Jacobian by automatic differentiation of the joint's own equations agrees with a numerical one, the hand-written one does not; on the new path the joint uses the AD Jacobian. - **notes:** ObjectJointGeneric with alternativeConstraints=True: Newton used the Jacobian of the default rotation constraints; the joint now differentiates its own equations - date resolved: **2026-10-02 00:26**, date raised: 2026-10-02 - **1.12.206** `BUG` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` MainSolverBase.ComputeAlgebraicEquations and ComputeODE1RHS raise a size mismatch (#2771) - description: solver.ComputeAlgebraicEquations(mbs) and solver.ComputeODE1RHS(mbs) link the residual as LinkedDataVector(systemResidual, start, start + n), but the third argument is the number of items: with algebraic equations (or ODE1 coordinates) the call raises 'LinkedDataVectorBase: size mismatch'. Found by the tests of revision2026b step RG14.2.9.1 (\#2745). - **notes:** solver.ComputeAlgebraicEquations(mbs) and solver.ComputeODE1RHS(mbs) raised a size mismatch when the system has algebraic equations or ODE1 coordinates; ComputeAlgebraicEquations returns the equations alone, no longer added to the previous residual - date resolved: **2026-10-01 23:50**, date raised: 2026-10-01 - **1.12.205** `BUG` `HIGH` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` RotXYZGTv\_qTemplate: wrong sign in d(G^T v)/dq for Tait-Bryan angles (#2770) - description: The derivative of G^T\*v with respect to the Tait-Bryan angles has entry (2,1) = -c1\*v\[0\] + ..., but d(s1\*v\[0\])/dq1 = +c1\*v\[0\]. It enters the Jacobian derivative of every torque on a NodeRigidBodyRxyz (CObjectRigidBody JacobianTtimesVector\_q, CNodeRigidBodyRxyz line 302); found by revision2026b step RG14.2.8.1 (\#2745), whose AD Jacobian of the torsional spring-damper differed from the numerical one in exactly this entry. - **notes:** RotXYZGTv\_qTemplate: the derivative of G^T v by the Tait-Bryan angles had a wrong sign in entry (2,1) (d(s1\*v0)/dq1 = +c1\*v0); it entered the Jacobian of every torque on a NodeRigidBodyRxyz - date resolved: **2026-10-01 23:30**, date raised: 2026-10-01 - **1.12.204** `BUG` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` declared output variables that cannot be read (#2768) - description: mbs.Inspect(item, exu.InspectType.OutputVariables) over every item of every MiniExample (\#2203) finds output variables an item declares but cannot compute: NodePoint2D RotationMatrix, Rotation, AngularVelocity, AngularVelocityLocal (GetOutputVariable failed); MarkerNodeODE1Coordinate Coordinates\_t (refused by MainMarker); ObjectANCFThinPlate Director2 (GetOutputVariableBody failed); ObjectANCFBeam AngularVelocity and AngularVelocityLocal (not implemented); ObjectRotationalMass1D AngularVelocityLocal (GetOutputVariableBody failed); and two that depend on the node: ObjectRigidBody on NodeRigidBodyRotVecLG Acceleration, AccelerationLocal, AngularAcceleration, AngularAccelerationLocal (the Lie group node has no angular acceleration), MarkerNodeRigid on the node of ObjectBeamGeometricallyExact AngularVelocity. Each is either implemented or no longer declared; the node-dependent ones need the body or marker to ask its node. - **notes:** Every output variable an item declares can now be read: the rotation outputs of NodePoint2D, Director1/Director2/ForceLocal/TorqueLocal of ObjectANCFThinPlate (which returned zeros before; ForceLocal and TorqueLocal are the membrane force and moment resultants per length), the angular velocity of ObjectANCFBeam, the accelerations of a rigid body on NodeRigidBodyRotVecLG, AngularVelocityLocal of ObjectRotationalMass1D, the angular velocity of a rigid marker on NodePointGround; markers on ODE1 coordinates no longer list Coordinates\_t. - date resolved: **2026-10-01 10:52**, date raised: 2026-10-01 - **1.12.203** `EXTENSION` `MEDIUM EFF` `resolved by: Claude-JG` MainSystem.Inspect (#2203) - description: add function MainSystem.Inspect(itemIndex, what, optArgs) which retrieves additional info on items like available output variables, node/marker types, etc. - **notes:** mbs.Inspect(itemIndex, what) asks an item what it provides and requests: output variables, type flags, requested node and marker types, access functions, as lists of exudyn enumeration members; what is a member of exu.InspectType, or None for all that apply. The output variables list the energies only where the item can compute them with its current parameters. - date resolved: **2026-10-01 10:16**, date raised: 2026-01-07 - **1.12.202** `TESTING` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` tests of user-facing features as test models (#2767) - description: A test of what a user does with Exudyn (items, output variables, sensors, utilities, and what they refuse) belongs into python/TestModels, where users look for examples, not into python/testing (maintainer, 2026-10-01): python/testing/test\_energies.py goes into the test model energiesTest.py and python/testing/test\_connectorOutputVariables.py becomes the test model connectorOutputVariablesTest.py; the rule is written into CLAUDE.md and docs/dev/WORKFLOW.md section 5. - **notes:** A test of what a user does with Exudyn is a test model in python/TestModels, where users look for examples: the energy tests are in energiesTest.py and energiesFlexibleBodiesTest.py, the output variables of connectors in connectorOutputVariablesTest.py; the rule is in CLAUDE.md and docs/dev/WORKFLOW.md. - date resolved: **2026-10-01 08:49**, date raised: 2026-10-01 - **1.12.201** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a sensor or object dictionary cannot hold KineticEnergy or PotentialEnergy (#2766) - description: The generated dictionary conversion of an OutputVariableType parameter cast the value to a 32-bit Index; KineticEnergy (bit 32) and PotentialEnergy (bit 33) then fail with 'Unable to cast Python instance of type OutputVariableType'. Found 2026-10-01 in RG9.4.2: mbs.AddSensor(SensorBody(..., outputVariableType=KineticEnergy)) raised. - **notes:** An outputVariableType beyond the 32nd bit (KineticEnergy, PotentialEnergy) can be given to sensors; an outputVariableType of -1 is refused. - date resolved: **2026-10-01 00:22**, date raised: 2026-10-01 - **1.12.200** `TESTING` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the MiniExample graphics test checks the transformation of the drawing (#2765) - description: Maintainer 2026-09-30 (RG2.3.3.6): the test sees more - a brick instead of a tetrahedron, the world basis drawn, bodies away from the origin, and the drawing transformation checked; the evaluation images in a 3D view. - **notes:** The graphics test of the MiniExamples checks that every body is drawn where its kinematics put it. - date resolved: **2026-09-30 23:59**, date raised: 2026-09-30 - **1.12.199** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a body rotated by a small angle is drawn unrotated (#2764) - description: AddBodyGraphicsData and AddBodyGraphicsDataColored skipped the rotation of a body's graphics when the diagonal of its rotation matrix was 1.f - which it is in single precision for any angle below about 3e-4 rad, while the off-diagonal terms are not zero. Found 2026-10-01 by the transformation check of the MiniExample graphics test (RG2.3.3.6): the spherical, generic and planar revolute joint examples drew their bodies 3e-5 m off after five steps. - **notes:** A rigid body rotated by a very small angle is drawn with its rotation; before, rotations below about 3e-4 rad were not drawn. - date resolved: **2026-09-30 23:59**, date raised: 2026-09-30 - **1.12.198** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` rightAngleFrame.py stops at the buckling load: drive it by displacement (#2762) - description: The test model rightAngleFrame.py (ANCF and geometrically exact beam) applies the load by a user function and the static solver stops near the critical load 1.088 N; it was not run by the suite (useGraphics). Maintainer 2026-09-30: drive the tip by displacement, a coordinate constraint with an offset user function, the reaction force being the load. - **notes:** The test model rightAngleFrame.py drives the frame by displacement and follows it past the buckling load of 1.088 N. - date resolved: **2026-09-30 23:34**, date raised: 2026-09-30 - **1.12.197** `CHANGE` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the mass switch of ObjectBeamGeometricallyExact becomes exu.special.beams.geometricallyExactLumpedMass (#2761) - description: exu.experimental.beamGeometricallyExactConsistentMass (RG4.8.4) stays as a switch, for tests with both mass matrices, but as a special setting: exu.special.beams.geometricallyExactLumpedMass, default False (the consistent mass); the experimental one goes (maintainer, 2026-09-30). - **notes:** The mass matrix of ObjectBeamGeometricallyExact is switched with exu.special.beams.geometricallyExactLumpedMass (default False: the element-consistent mass); exu.experimental.beamGeometricallyExactConsistentMass is gone. - date resolved: **2026-09-30 23:27**, date raised: 2026-09-30 - **1.12.195** `FIX` `MEDIUM EFF` `resolved by: Claude-JG` shadows (#2308) - description: in case modelCentricView=False, lights with useCameraFrame=True have erratic shadows in OpenGL mode - **notes:** Shadows in the OpenGL renderer no longer flicker or disappear with a camera-centric view and lights in the camera frame. - date resolved: **2026-09-30 23:09**, date raised: 2026-02-19 - **1.12.194** `EXTENSION` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev runs the pytest files and the MiniExample performance run (#2760) - description: exudev has commands for runTestSuite, runTestExamples and runPerformanceTests, but none for the pytest files of python/testing (graphics regression, MiniExample graphics, settings, dialogs, tools), none for runMiniExamplePerformance.py and none to re-record the graphics references. New: exudev pytest \[--graphics\] \[--gate\] \[--record\] \[-k\] \[--processes\], exudev perf --mini \[--full\] \[--processes\] \[--only\] \[--compare\]; build --complete also runs pytest. - **notes:** exudev pytest runs the pytest files of python/testing (--graphics for the graphics tests, --record to re-write their references); exudev perf --mini runs the performance measurement of the MiniExamples. - date resolved: **2026-09-30 21:59**, date raised: 2026-09-30 - **1.12.193** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` examples in subfolders are not run, and two of them fail (#2757) - description: runTestExamples.py runs python/Examples/\*.py only; the subfolders (FurtherExamples, publications, ...) are not run. Found 2026-09-30 (revision2026b RG12.30.4) by running six of them: FurtherExamples/fourBarKinematicTreeUF.py fails with 'module object is not callable' (copy), publications/CND2022PieberNtarladimaGerstmayr/fixedFixedANCFALEdiscreteMasses.py with 'exudyn.basicUtilities has no attribute pi' - both from earlier import cleanups, not from RG12.30. - **notes:** The examples in the subfolders of python/Examples are run with the other examples and work again; ClearWorkspace() no longer breaks a later import of exudyn.basicUtilities; a static solve with a user-function load on an ALE ANCF cable no longer fails with an inconsistent load jacobian. - date resolved: **2026-09-30 20:03**, date raised: 2026-09-30 - **1.12.192** `TESTING` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` graphics regression test: every item through its MiniExample (#2751) - description: The last part of \#2704 (resolved 2026-09-29 with RG2.3.3.1 to RG2.3.3.4): take every item through its MiniExample - which every item but three has since RG13.6 (\#2732) - and store the graphics fingerprint of each (SC.renderer.GetGraphicsData(), counts and metrics) as a reference. revision2026b step RG2.3.3.5. - **notes:** Every item's drawing is checked through its MiniExample: the graphics data at the start and after a few steps are compared with stored references. - date resolved: **2026-09-30 19:04**, date raised: 2026-09-29 - **1.12.191** `FIX` `MEDIUM EFF` `resolved by: Claude-JG` FEMinterface (#2321) - description: meshes imported from NGsolve lead to triangles with wrong orientation as compared to GraphicsData - **notes:** The surface triangles of a mesh imported with FEMinterface.ImportMeshFromNGsolve point outward, as those of the other imports; an FFRF body from NGsolve is lit on its outside. - date resolved: **2026-09-30 18:52**, date raised: 2026-03-03 - **1.12.190** `FIX` `MEDIUM EFF` `resolved by: Claude-JG` ZoomAll (#2309) - description: does not include trackMarker position (and orientation); fix that even for moving markers in modelCentricView zoom all is possible - **notes:** ZoomAll takes a tracked marker (camera.trackMarker) into account: the scene is centered and sized as the view draws it, with the marker's position and orientation tracked. - date resolved: **2026-09-30 18:43**, date raised: 2026-02-19 - **1.12.189** `FIX` `LOW EFF` `resolved by: Claude-JG` Marker positions (#1813) - description: wrong representation of marker positions in AnimateModes for deformation scaling=0 - **notes:** The markers on a superelement (MarkerSuperElementPosition, MarkerSuperElementRigid) are drawn on the body also when visualizationSettings.bodies.deformationScaleFactor scales its deformation, e.g. for a mode of amplitude 0 in AnimateModes. - date resolved: **2026-09-30 18:34**, date raised: 2024-04-08 - **1.12.188** `CHANGE` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` scripts and modules use exudyn.graphics where it has the replacement, not exudyn.graphicsDataUtilities (#2759) - description: After \#2756 the scripts under python/ imported GraphicsDataRectangle, GraphicsDataOrthoCubeLines and the color4 names from exudyn.graphicsDataUtilities (41 star imports among them) instead of using exudyn.graphics. The maintainer asked for the scripts and modules to be adapted: graphics.Lines, graphics.BrickXYZ(addFaces=False, addEdges=True), graphics.color; only the mesh functions without a replacement keep an import from graphicsDataUtilities. - **notes:** The scripts and modules of Exudyn use exudyn.graphics for rectangles (graphics.Lines), line cubes (graphics.BrickXYZ with addFaces=False) and colors (graphics.color); exudyn.graphicsDataUtilities is imported only for its mesh functions. - date resolved: **2026-09-30 18:22**, date raised: 2026-09-30 - **1.12.187** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the pages of ObjectFFRF and ObjectFFRFreducedOrder link example pages that the PDF leaves out (#2758) - description: The descriptions of ObjectFFRF and ObjectFFRFreducedOrder (\#2734/\#2735) link \[\](\#examples-ngsolveffrf), \[\](\#examples-ngsolvecmstutorial) and \[\](\#testmodels-objectffrfreducedordertest). The PDF build excludes the example and test model pages (conf.py), so the three links are unresolved there (myst.xref\_missing). An item page names its examples through the examples field, which the page lists with github links; checkDefinitions shall reject a link to an example page. - **notes:** The pages of ObjectFFRF and ObjectFFRFreducedOrder name their complete models (NGsolveFFRF.py, NGsolveCMStutorial.py, objectFFRFreducedOrderTest.py) and list them with their github links; the PDF documentation no longer reports unresolved references on them. - date resolved: **2026-09-30 17:52**, date raised: 2026-09-30 - **1.12.186** `EXTENSION` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` explicit solvers: the states updated in the PostNewton step (#2754) - description: Explicit solvers do no PostNewton step, so contact, friction, switching states, rotation counters and sliding joint elements are not updated (\#830 added a warning). Concept (maintainer 2026-09-30): check whether a PostNewton step is needed at all; update the data variables in the explicit integration similar to GeneralContact - at the beginning of a step, or more correctly in every stage of a multi-stage method; check every object with a PostNewton step against the concept; a test sweeping all explicit integrators, like contactComparisonTest.py; \#2109 (DOPRI5 step size at discontinuities) may be resolved by it or give insight. Planned as revision2026b step RG4.16. - **notes:** the explicit solvers perform the PostNewton step after every step (contact, friction, switching states) and keep the scheme of the implicit solvers: states fixed during the stages of a step, updated after it, the step repeated when a state changed; tested with all explicit integrators (explicitSolversPostNewtonTest.py) - date resolved: **2026-09-30 14:48**, date raised: 2026-09-30 - **1.12.185** `FIX` `HIGH EFF` `resolved by: Claude-JG` DOPRI5 (#2109) - description: DOPRI5 automatic step size not working well with discontinuities (ContactSphereSphere, etc.) - **notes:** explicit solvers with automatic step size (DOPRI5, ODE23): an accepted step keeps its step size while a discontinuous iteration (contact, friction) repeats it; before, the step size proposed for the next step was used for the repetition, which could reject the same step forever; ObjectContactSphereSphere, ObjectContactSphereTorus and ObjectContactSphereTriangle recommend a step size also where the contact ends, as ObjectContactCoordinate does, which makes the release accurate with large steps; results of models with these contacts change slightly - date resolved: **2026-09-30 14:48**, date raised: 2025-06-22 - **1.12.184** `CHANGE` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudyn.utilities imports less (#2756) - description: Maintainer 2026-09-30: remove from exudyn.utilities the imports of the beam generators (GenerateStraightLineANCFCable2D, GenerateSlidingJoint, GenerateAleSlidingJoint, GenerateStraightBeam - in exudyn.beams), of CreateDistanceSensorGeometry, CreateDistanceSensor, DrawSystemGraph (mbs.Create..., mbs.Draw...) and of graphicsDataUtilities (the old colors color4red, ... shall not be promoted); update the exudev scripts checker, all models under python/, and the documentation with the workarounds. Planned as revision2026b step RG12.30. - **notes:** from exudyn.utilities import \* no longer provides the beam generators (import them from exudyn.beams), the MainSystem extensions CreateDistanceSensor..., DrawSystemGraph (use mbs.CreateDistanceSensor(...), mbs.DrawSystemGraph(...)) and the names of exudyn.graphicsDataUtilities (the colors color4red... are graphics.color.red...; import the rest from exudyn.graphicsDataUtilities); GraphicsDataRectangle and GraphicsDataOrthoCubeLines are deprecated; exudev scripts names every affected line - date resolved: **2026-09-30 13:53**, date raised: 2026-09-30 - **1.12.183** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` explicit solvers: the warning about the PostNewton step is wrong (#2755) - description: The warning added for \#830 (revision2026b RG4.15.3) says that explicit solvers do not perform the PostNewton step; they do, after every step, through the discontinuous iteration of CSolverBase. The warning is removed; found in revision2026b step RG4.16.1. - **notes:** the warning at the start of an explicit solve about objects with a PostNewton step is removed: it was wrong - explicit solvers perform the PostNewton step after every step, like the implicit solvers - date resolved: **2026-09-30 11:33**, date raised: 2026-09-30 - **1.12.181** `BUG` `HIGH EFF` `resolved by: Claude-JG` ContactSphereTorus (#2127) - description: check torques on both bodies, as there seems to be momentum conservation issues in ball bearings - **notes:** ObjectContactSphereTorus: the torque of the normal contact force on the torus is applied also without friction; before, a free torus (e.g. the ring of a ball bearing) did not conserve angular momentum - date resolved: **2026-09-30 07:33**, date raised: 2025-07-03 - **1.12.180** `FIX` `MEDIUM EFF` `resolved by: Claude-JG` NumericalJacobianODE1RHS (#1424) - description: add case for duplicated ODE1 coordinates if connector has two markers for the same object, same as ltgODE2numDiff - **notes:** the numerical Jacobian of ODE1 equations differentiates an ODE1 coordinate that an object addresses twice only once; before, its column was added twice, which slowed Newton's convergence - date resolved: **2026-09-30 07:33**, date raised: 2023-02-08 - **1.12.179** `BUG` `MEDIUM EFF` `resolved by: Claude-JG` PostNewton (#830) - description: PostNewton missing in explicit solvers; add warning or add after single steps (but exclude in contact computation!) - **notes:** explicit solvers (RK, DOPRI5, ...) warn at the start of a solve about objects that update their state in the PostNewton step of the implicit solvers - contact, friction, switching, rotation counters, sliding joints - which the explicit solvers do not update - date resolved: **2026-09-30 07:33**, date raised: 2021-12-15 - **1.12.178** `EXTENSION` `LOW EFF` `resolved by: Claude-JG` GeometricallyExactBeam2D (#2208) - description: add test for 3-node element - **notes:** ObjectBeamGeometricallyExact2D: the 3-node (quadratic) element is tested - one element reproduces the Timoshenko cantilever, and it converges with fourth order for large deformation (test model geometricallyExactBeam2DquadraticTest.py) - date resolved: **2026-09-30 07:18**, date raised: 2026-01-08 - **1.12.177** `BUG` `HIGH EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectBeamGeometricallyExact (3D) has defects and is under development: analyse the implementation (#2730) - description: The maintainer, 2026-09-28: 'The 3D GeometricallyExactBeam has some defects and is still under development. So, you would find some errors in the implementation - so keep this item open and add a step and issue to RG4.' Its reference page (4 words of description) stays open in RG13.5.2 until the analysis says what the element does and what it does not; an item found with a larger defect while it is documented gets an RG4 step like this one rather than a fix inside RG13. revision2026b step RG4.8. - **notes:** ObjectBeamGeometricallyExact is analysed and completed: body markers and output variables (section forces, strains, rotations) are available, the Jacobian is complete, the element is stress-free in the reference configuration of its nodes (curved and twisted beams), the mass matrix is element-consistent, and the element is tested against the literature (45-degree bend, right-angle frame buckling, dynamic right-angle cantilever); its reference page and MiniExample describe it - date resolved: **2026-09-30 01:43**, date raised: 2026-09-28 - **1.12.176** `CHECK` `MEDIUM EFF` `resolved by: Claude-JG` GeometricallyExactBeam (#1273) - description: check quadratic velocity terms - **notes:** ObjectBeamGeometricallyExact: element-consistent mass matrix and quadratic velocity vector, for the linearly interpolated velocity field of the element; a rigid motion is represented exactly at any mesh (the lumped mass of the nodes gave e.g. a 22 % too long period for a one-element pendulum); dynamic results change; exu.experimental.beamGeometricallyExactConsistentMass=0 switches back to the lumped mass for comparison - date resolved: **2026-09-30 01:32**, date raised: 2022-09-24 - **1.12.175** `FIX` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectBeamGeometricallyExact: output variables (#2753) - description: the definition declares the output variables Rotation, StrainLocal and CurvatureLocal, which GetOutputVariableBody does not compute - asking for them stops with an internal error; ForceLocal and TorqueLocal, the section forces and moments, are missing (maintainer); planned as revision2026b step RG4.8.10 - **notes:** ObjectBeamGeometricallyExact: the output variables Rotation, RotationMatrix, AngularVelocity, AngularVelocityLocal, StrainLocal, CurvatureLocal, ForceLocal and TorqueLocal are available; strains and section forces are constant in an element; Rotation, StrainLocal and CurvatureLocal were declared before but stopped with an internal error - date resolved: **2026-09-30 00:16**, date raised: 2026-09-30 - **1.12.174** `TESTING` `NORMAL` `MEDIUM EFF` `resolved by: Claude-JG` GeometricallyExactBeam (#1499) - description: check for advanced right-angle frame - **notes:** ObjectBeamGeometricallyExact: tested with the lateral buckling of the right-angle frame, which buckles at the published critical load of 1.088 N (test model geometricallyExactBeamRightAngleFrame.py) - date resolved: **2026-09-30 00:04**, date raised: 2023-04-08 - **1.12.173** `FIX` `HIGH` `MEDIUM EFF` `resolved by: Claude-JG` GeometricallyExactBeam (#1494) - description: add reference configuration to residual and jacobian - **notes:** ObjectBeamGeometricallyExact: the element is stress-free in the reference configuration of its nodes, so a curved or twisted beam is modelled by placing and orienting its nodes; before, every element was stress-free only when straight along its local x axis - date resolved: **2026-09-29 23:54**, date raised: 2023-04-06 - **1.12.172** `FIX` `MEDIUM EFF` `resolved by: Claude-JG` GeometricallyExactBeam (#1550) - description: add F\_Lie\*Glocal\_q term for Jacobian to improve convergence - **notes:** ObjectBeamGeometricallyExact: the Jacobian contains the terms of the derivative of Glocal and of the rotation matrix; see \#1100 - date resolved: **2026-09-29 23:46**, date raised: 2023-05-02 - **1.12.171** `EXTENSION` `HIGH EFF` `resolved by: Claude-JG` GeometricallyExactBeam3D (#1100) - description: finalize implementation and fix jacobian computation - **notes:** ObjectBeamGeometricallyExact: the Jacobian is complete - the derivatives of the rotation matrices, of the G matrices and of the SE(3) tangent operator are included, and the derivative of the quadratic velocity vector with respect to the velocities; large deformations with Tait-Bryan nodes converge in the static solver, which failed before - date resolved: **2026-09-29 23:46**, date raised: 2022-05-23 - **1.12.169** `EXTENSION` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` exudev issue plot: the issues over time as a matplotlib figure (#2752) - description: The maintainer, 2026-09-29: 'exudev issue plot' opens a matplotlib figure with the issues over time - total, closed and open - and, on a second scale, total and open bugs and fixes, with a legend. revision2026b step RG10.13. - **notes:** exudev issue plot shows the issues over time - total, closed, open, and the bugs and fixes on a second axis; --save FILE writes the figure. - date resolved: **2026-09-29 21:41**, date raised: 2026-09-29 - **1.12.168** `EXTENSION` `NORMAL` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectContactCoordinate gets the contact law of ObjectContactSphereSphere: stiffness exponent, restitution and impact models (#2750) - description: The maintainer, 2026-09-29: ObjectContactCoordinate should get the contact law of ObjectContactSphereSphere - contactStiffnessExponent, restitutionCoefficient, impactModel, minimumImpactVelocity (Hunt-Crossley and Gonthier/Carvalho-Martins); the comparison test of the three contact objects (RG4.15.1) extends to these laws. revision2026b step RG4.15.2. - **notes:** ObjectContactCoordinate has the contact law of ObjectContactSphereSphere: contactStiffnessExponent, restitutionCoefficient, minimumImpactVelocity and impactModel (Hunt-Crossley, Gonthier et al. / Carvalho-Martins); with an impact model its data node has a second coordinate. - date resolved: **2026-09-29 21:27**, date raised: 2026-09-29 - **1.12.167** `FIX` `MEDIUM EFF` `resolved by: Claude-JG` mbs.GetDictionary (#1888) - description: does not work for symbolic userfunctions - **notes:** mbs.SetDictionary() accepts the dictionary of a model with a symbolic user function, as mbs.GetDictionary() writes it; the copy keeps the function symbolic. - date resolved: **2026-09-29 21:27**, date raised: 2024-10-11 - **1.12.166** `TESTING` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` one drop, three contact objects: ObjectContactCoordinate, ObjectContactSphereSphere, ObjectContactSphereTriangle give the same motion (#2749) - description: The maintainer, 2026-09-29, as a check in compensation for \#738: a ball hitting the ground computed with ObjectContactCoordinate (one coordinate), ObjectContactSphereSphere (a large ground sphere) and ObjectContactSphereTriangle (a ground triangle), with the same linear penalty law, must give the same motion; all together in one test. revision2026b step RG4.15.1. - **notes:** A test drops a ball on the ground with ObjectContactCoordinate, ObjectContactSphereSphere and ObjectContactSphereTriangle and checks that the three give the same motion. - date resolved: **2026-09-29 20:15**, date raised: 2026-09-29 - **1.12.165** `DOCU` `HUGE EFF` `raised by: Claude-JG` `resolved by: Claude-JG` RG13.5: the documentation of the items, written by the development documents of RG13.4 - nodes, objects, markers, loads, sensors (#2725) - description: The maintainer, 2026-09-27, after reading the node, load and sensor documents of RG13.4: those three are complete; 'start a new step RG13.5, which adds according documentation for these types, again adding 13.5.1 for nodes, .2 for objects, ...'. For loads the generalized forces keep their frames: a load is given in global or local coordinates, and the transformation belongs in the equation. For the slope nodes, the interpretation of the slopes goes into the detailed description of each node. RG13.5.0 is the generated frame and the general section per kind (definitions/itemKindDefinitions.py), before the pages are written. revision2026b step RG13.5. - **notes:** The reference manual describes every item - nodes, objects, markers, loads, sensors - with a general section per kind of item, and each item with what is its own. - date resolved: **2026-09-29 20:15**, date raised: 2026-09-27 - **1.12.164** `TESTING` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a graphics regression test on SC.renderer.GetGraphicsData(): counts per item, and metrics of positions and colors (#2704) - description: The maintainer, 2026-09-27: 'File graphicdata test as step. It could include also metrics for positions, colors - mean/min/max - so the content is also checked.' A set of models, each under several visualization settings, reduced to a fingerprint from SC.renderer.GetGraphicsData() (\#2700) and compared with a stored reference: the NUMBER of lines, spheres, circles, texts and triangles per item exactly, and the CONTENT through metrics - min, max and mean of the points per coordinate, of the colors per channel, of radii and normals - with a tolerance, because the data is float32 and must compare across compilers. Texts are compared as their strings. The fingerprint is small enough to be a readable JSON reference, so a change shows in git diff as 'ObjectRigidBody 3: 12 triangles -\> 10' or 'mean z of the triangles of object 0 moved by 0.2'. No window is opened. revision2026b step RG2.3.3. - **notes:** A graphics regression test compares what the renderer draws - counts and metrics of the graphics data per item under the most used settings and with graphics user functions - and low-resolution raytracer images with stored references. - date resolved: **2026-09-29 20:15**, date raised: 2026-09-27 - **1.12.159** `BUG` `MEDIUM EFF` `resolved by: Claude-JG` ObjectContactCoordinate (#738) - description: modified Newton does not work, no Jacobian update computed when switching - **notes:** ObjectContactCoordinate switches its contact with a Jacobian update; a test compares it with the sphere-sphere and sphere-triangle contact on the same drop (\#2749). - date resolved: **2026-09-29 20:15**, date raised: 2021-08-13 - **1.12.158** `TESTING` `HIGH` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` a manual check of the render window and the dialogs before a release, on each platform (#2748) - description: The maintainer, 2026-09-29 (tmp/ManualGraphicsCheck): nothing automatic checks that a human can use the render window and the dialogs - keys, mouse, tkinter windows, focus, fonts, window placement. A check list for one person and one hour per platform (Windows, Ubuntu, macOS) before each release, with a model that has an item of every kind: the list into the developer documentation, the model into python/testing. revision2026b step RG2.4; RG1.4 waits for it. - **notes:** The developer documentation has a check list of the render window and the dialogs, for a person on each platform before a release, with a model that has an item of every kind (python/testing/guiManualCheckModel.py). - date resolved: **2026-09-29 19:58**, date raised: 2026-09-29 - **1.12.157** `FIX` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the GitLab job check\_docstrings fails, and no local gate runs pydoclint (#2747) - description: The maintainer, 2026-09-29, tmp/gitLabRunsFailed/check\_docstrings.txt: pydoclint reports 29 findings outside its baseline - 25 DOC108 in the generated itemInterface.py (the user function parameters carry their Protocol type since \#2664, and the configuration says no type hints in signatures), three DOC202 (a Returns: None section without a return: GUI.ApplyColumnWidths, GUI.StoreWindowGeometry, overrideSettings.StoreDialogGeometry) and one DOC104 (argument order in resultsMonitor.MonitorResults). No local gate runs pydoclint, so the CI job is the first to see it. Fix the four, record the deliberate DOC108 in the baseline, and add pydoclint to exudev generate --all-checks. revision2026b step RG10.12. - **notes:** The docstring check of the CI passes again, and exudev generate --all-checks runs it locally. - date resolved: **2026-09-29 19:52**, date raised: 2026-09-29 - **1.12.156** `DOCU` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` developer documentation names paths of the old main/ directory (#2743) - description: Found in revision2026b step RG13.7: docs/dev/WORKFLOW.md and docs/dev/README.md name main/setup.py, main/obj/cppsrc.vcxproj, main/sources.json and main/pyproject.toml; the files are setup.py, msvc/cppsrc.vcxproj, sources.json and pyproject.toml at the repository root. The layout block of the README also carries hand-kept counts that are wrong (24 mini examples, 139 test models) and a src/ listing without the Impl\* directories. revision2026b step RG3.28. - **notes:** The developer documentation names the build files where they are: setup.py, pyproject.toml and sources.json at the repository root, the project file in msvc/. - date resolved: **2026-09-29 19:10**, date raised: 2026-09-29 - **1.12.153** `DOCU` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` developer documentation: how to set up a new item (#2742) - description: The maintainer, 2026-09-29: a section 'How to set up a new item in Exudyn' - the definitions and how they work, how to add a simple item, with focus on the descriptions, parameter and function descriptions, miniExample and outputVariables; what to run; which files the generator writes for a new className (C/Main/Visu headers, object factory registration, Python interface, stubs, docs, MiniExample), and what is written by hand (the .cpp with the computation and UpdateGraphics, CheckPreAssembleConsistency in checkPreAssembleConsistencies\.cpp, the project file). The parts exist in CODING\_STYLE.md section 9, ARCHITECTURE.md and definitions/README.md, scattered; one page brings them together and refers to the rest. revision2026b step RG13.7. - **notes:** The developer documentation has a page on how to set up a new item: the definition, which files the generator writes, the C++ to write for each kind of item, and what to run. - date resolved: **2026-09-29 18:54**, date raised: 2026-09-29 - **1.12.152** `BUG` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` the cable and beam shape markers accept any body: on a wrong one they cast it to an ANCF cable (#2731) - description: Found while documenting the markers, revision2026b step RG13.5.3, 2026-09-28: MarkerBodyCable2DShape, MarkerBodyCable2DCoordinates and MarkerBodyBeamShape have no consistency check of the body they are attached to. Assemble() accepts them on a rigid body, and ComputeMarkerData then casts the body to CObjectANCFCable2DBase or CObjectANCFCable: with range checks this ends in 'InternalError: call to ConstSizeVectorBase::SetNumberOfItems with newNumberOfItems \> dataSize', in the fast module (no range checks) it is undefined behaviour. The analysis: which bodies each of the three markers can serve (ANCFCable2D and ALEANCFCable2D; ANCFCable), a CheckPreAssembleConsistency that says so, and whether MarkerBodyBeamShape, described as for 'a 3D beam finite element', should serve other beams. revision2026b step RG4.9 (maintainer's rule: a larger defect found while documenting gets an RG4 step). - **notes:** Assemble() refuses MarkerBodyCable2DShape and MarkerBodyCable2DCoordinates on anything but ObjectANCFCable2D or ObjectALEANCFCable2D, and MarkerBodyBeamShape on anything but ObjectANCFCable - they cast the body to a cable before. MarkerBodiesRelativeTranslationCoordinate and MarkerBodiesRelativeRotationCoordinate are coordinate markers only; position connectors and loads no longer accept them, and Assemble() refuses bodies without the position or orientation they need. - date resolved: **2026-09-29 18:38**, date raised: 2026-09-28 - **1.12.151** `BUG` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectContactCoordinate ignores activeConnector, and its output variable Distance raises (#2735) - description: Found while documenting the connectors, revision2026b step RG13.5.2.4, 2026-09-28: CObjectContactCoordinate::ComputeODE2LHS computes the contact force without looking at parameters.activeConnector, so the connector cannot be switched off as its parameter says; and GetOutputVariableTypes declares Distance while GetOutputVariableConnector raises 'not implemented', so a SensorObject asking for it passes Assemble() and fails during the simulation. Small, but found by the maintainer's rule it becomes an RG4 step: revision2026b step RG4.11. \[2026-09-28, Claude-JG\]: Extended in RG13.5.2.5, 2026-09-28: a scan of all objects for GetOutputVariableConnector that raises 'not implemented' while GetOutputVariableTypes declares types found four: ObjectContactCoordinate (Distance), ObjectContactCircleCable2D (Distance), ObjectJointRevolute2D (Displacement, Rotation) and ObjectJointPrismatic2D (Distance, Rotation). A sensor asking for one of them passes Assemble() and fails during the simulation. Either implement the output variables or declare none. - **notes:** Output variables of four connectors: ObjectContactCoordinate gives Distance (the gap) and adds no force with activeConnector=False; ObjectJointRevolute2D gives Displacement; ObjectJointPrismatic2D gives Distance along the axis and the relative Rotation; ObjectContactCircleCable2D declares none. They raised 'not implemented' during the simulation before. - date resolved: **2026-09-29 18:09**, date raised: 2026-09-28 - **1.12.150** `BUG` `MEDIUM EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectGenericODE2 and ObjectKinematicTree admit the general body markers, which fail during the simulation (#2734) - description: Found while documenting the super elements, revision2026b step RG13.5.2.3, 2026-09-28: both objects declare the access function types TranslationalVelocity\_qt and AngularVelocity\_qt (and GenericODE2 DisplacementMassIntegral\_q), which their own markers need - MarkerSuperElementPosition/Rigid, MarkerKinematicTreeRigid - to pass CSystem::CheckSystemIntegrity. The same types admit MarkerBodyPosition, MarkerBodyRigid and MarkerBodyMass, whose computation calls GetAccessFunctionBody, and that raises 'not available' for both objects. The declaration now carries bodyMarkers=False, which the item pages use; the analysis: let the integrity check use it too, so that Assemble() refuses the combination. revision2026b step RG4.10. - **notes:** Assemble() refuses MarkerBodyPosition, MarkerBodyRigid and MarkerBodyMass on ObjectGenericODE2 and ObjectKinematicTree, which provide access only for their own markers - they raised during the simulation before; a super element marker needs a super element and a kinematic tree marker a kinematic tree. - date resolved: **2026-09-29 18:09**, date raised: 2026-09-28 - **1.12.149** `BUG` `HIGH` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` ObjectKinematicTree: the position Jacobian of a prismatic joint rotates the axis twice (#2740) - description: Found while writing the page of MarkerKinematicTreeRigid (\#2738, revision2026b step RG13.5.3.1). CObjectKinematicTree::ComputeJacobian computes axis = rotJoint\*localAxis, which is the global joint axis, and for a prismatic joint then sets positionJacobian column = rotJoint\*axis - the rotation applied twice. It is right only while the joint frame leaves the axis unchanged. Measured: link 0 RevoluteZ held at q0, link 1 PrismaticX on it, a LoadForceVector of 1 N along the prismatic axis on a MarkerKinematicTreeRigid of link 1, mass 2: after 1 s q1 = 0.25 for q0 = 0, and q1 = 0 for q0 = pi/2 (the column is -e\_x instead of e\_y). Every marker, load and connector on a link at or behind a rotated prismatic joint gets wrong generalized forces. The fix is one line (positionJacobian column = axis) and a test model with the case above. revision2026b step RG4.13. - **notes:** ObjectKinematicTree: a force, torque or connector on a MarkerKinematicTreeRigid behind a prismatic joint whose axis is rotated - by a parent link or by its joint transformation - acts in the right direction; the Jacobian rotated the prismatic axis twice, which gave wrong generalized forces, e.g. none at all behind a revolute joint at 90 degrees. - date resolved: **2026-09-29 14:44**, date raised: 2026-09-29 - **1.12.148** `DOCU` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` parameter tables: the symbol in the name column, and columns squeezed in the PDF (#2741) - description: The maintainer, 2026-09-29: (1) the symbol of a parameter, e.g. the force f of LoadForceVector, is appended to the name in the parameter tables; it belongs at the very beginning of the description, '(symbol: f) ', where it stays visible when a column is added or the name column is narrow. (2) In the PDF, a table with long descriptions gets name, type and default value columns of a few letters, because LaTeX sizes the columns by content; the parameter tables and the similar ones need minimum widths in the PDF. revision2026b step RG13.5.0.8. - **notes:** In the parameter tables of the reference manual the symbol of a parameter opens its description, '(symbol: f)'; in the PDF the columns of these tables have fixed widths, so that a long description no longer squeezes the name, type and default value. - date resolved: **2026-09-29 14:26**, date raised: 2026-09-29 - **1.12.147** `DOCU` `NORMAL` `LOW EFF` `raised by: Claude-JG` `resolved by: Claude-JG` MarkerSuperElementRigid and MarkerKinematicTreeRigid keep text in HTML comments (#2738) - description: The detailed descriptions of MarkerSuperElementRigid and MarkerKinematicTreeRigid carry tables and equations inside HTML comments (\