GSoC 2022 Report Timo Stienstra : Enhancing the Joints Framework - sympy/sympy GitHub Wiki

This report summarizes the work I have done during GSoC 2022 for SymPy.

Project Synopsis

The aim of this project was to further develop the construction of systems from bodies and joints. This was done in three phases with a preparation on beforehand. The first phase focused on fixing existing bugs and adding documentation in order to make the joints framework ready for the upgrades. The second face consisted of implementing the intermediate frames in combination with a joint axis, which allows for more complex joint definitions. In the third phase multiple new joints were added, namely the cylindrical joint, planar joint and at last the spherical joint.

Contribution Overview

This section discusses my GSoC 2022 related contributions to SymPy. The contributions are split in four parts: (0) Preparation phase of GSoC. (1) Improved documentation. (2) Enhanced joints definition. (3) New joints.

GSoC preparation

During the application progress of GSoC I have done the following contributions, which were mainly focused on fixing existing bugs and issues:

  • Raised and closed issue #23358 on the incorrect velocity calculation of Point.vel with merged PR #23362.
  • Opened draft PR #23359 proposing a zero velocity check to the velocity and acceleration theorems.
  • Raised issue #23382 which advises to compute the velocity in the Point.vel method in a recursive way.
  • Closed issue #22956 on incorrect PinJoint velocity with merged PR #23392.
  • Raised and closed issue #23393 which was a discussion on what the definition of a velocity in a frame is.

Improved Documentation

In the first official phase of GSoC the focus lay on improving the documentation together with fixing existing bugs. The major contributions during this phase was writing documentation of the joints framework in general including images explaining the joints. One of the main issues I ran into during this phase was the sub-optimal definition of a joint in general, which became the main focus of phase 2. Below is a list of all contributions during phase 1.

  • Participated in the still open issue #21964 on making the Body analogous to ReferenceFrame.
  • Reviewed still open PR #23580 on returning kinematic equations implicitly in KanesMethod.
  • Merged PR #23628 which enhances the Point.acc method to also compute the acceleration if the velocity is not yet defined.
  • Merged PR #23705 adding the four-bar-linkage example using the joints framework.
  • Raised issue #23706 on the visibility of images when using the new dark theme.
  • Closed issue #21705 on the need of a figure explaining the Joint arguments with merged PR #23730.
  • Raised issue #23741 discussing how ReferenceFrame and Point should go about saving states.
  • Merged PR #23890 converting the joint images introduced in #23730 to svg.

Enhanced Joint Definition

During phase 1 I ran into a suboptimal definition in the Joint class. Namely, that a so called parent_axis and child_axis were used to almost magically create an intermediate frame from which the joint was defined.

In the by my mentors advised paper by Seth et al. a mobilizer definition is proposed. One of the notable differences between the mobilizer definition and the joint definition in SymPy at the time is the use of intermediate frames for both the parent body and child body. So after some discussing it was chosen to implement these intermediate frames (abbreviated interframes) in the Joint class. However one of the major advantages of the parent_axis and child_axis was there intuitive and simple use. In order to keep this advantage, the options that one can supply a vector to an interframe argument was added. If done so the interframe is oriented such that its X axis aligns with this provided vector.

Below is again a list of all contributions during phase 2.

  • Raised and closed issue #23913 on the problem that the use of temporary relationships between ReferenceFrames in the Joint class can lead to deleting correct relations with merged PR #23920.
  • Merged PR #23920 changing the definition of a Joint to use intermediate frames.
  • Raised and closed issue #23933 on the unnecessary dependency of test_pinjoin_arbitrary_axis on test_functions.py with merged PR #24028.
  • Merged PR #23981 adding an optional frame argument to RigidBody.parallel_axis and implementing Body.parallel_axis.
  • Merged PR #23982 changing Body to always have an inertia, also when representing a Particle. This partially solves issue #23269.

New Joints

In this final phase the main contributions were the implementation of the CylindricalJoint, PlanarJoint and SphericalJoint. One notable other change was reverting the in phase 2 introduced JointAxisMixin.

  • Raised issue #1929 in the symengine on the problem of stackability of null Matrices.
  • Raised and closed issue #24005 on the problem that a CI slow test 2 failed due to a timeout. However due to irreproducibility this issue was also closed.
  • Merged PR #24028 implementing a generic coordinate generation helper.
  • Merged PR #24037 implementing the CylindricalJoint.
  • Merged PR #24046 implementing the PlanarJoint.
  • Merged PR #24053 implementing the SphericalJoint in which #24098 is also fixed.
  • Merged PR #24080 reverting the JointAxisMixin for simplicity, which was introduced in #23920.
  • Merged PR #24085, which simplifies the angular velocity computation in orient_body_fixed and orient_space_fixed, while also fixing closed issue #23075.

Conclusions

When comparing the contributions to the initial proposal, it is fair to say that the proposed contributions have been met. However the number of implemented examples is a bit lower than anticipated, but at the same time there has also been chosen for a more flexible implementation than the quaternion support for the parent_axis and child_axis. The final implementation actually uses a ReferenceFrame, which can be created by using for example a quaternion. Furthermore there have also been multiple smaller contributions, which are outside the original scope of the proposal. Overall I have learned a lot during this project and hope to keep contributing to SymPy in the future, partially also in my master Thesis.

Future Work

  • Generalize the abstract class for method, i.e. _Method
  • Refactor the design of how bodies and loads are used \begin{itemize}
    • Deprecate Body, instead create a abstract _Body for RigidBody and Particle
    • Create classes for the loads, e.g. _Load, Force, Torque \end{itemize}
  • Implement a more easy method to add constraints in the joints framework
  • Implement a kdes_choice = 'efficient' argument for the joints, which uses the most ideal choice of the generalized coordinates based on the paper of Mitiguy and Kane
  • Add more examples on using the joints framework

Acknowledgments

This project would not have been possible without my mentors, who reviewed most of my PRs and helped me to make lots of design decisions. I would like to thank Jason K. Moore specifically for his push to always keep thinking about backwards compatibility. Sudeep Sidhu I would like to thank for providing the good initial setup of the joints framework. And Sam Brockie for his quick replies and the many reviews and discussions on what would be the best way to implement a certain feature. At last I would also like to thanks all contributors to SymPy for helping getting started, finding bugs, reviewing and so on.

⚠️ **GitHub.com Fallback** ⚠️