Another week of Summer of Code progress.
This week, there was a lot less new functionality added, and a lot more refinement of behaviors (and more documentation added). The code got split into multiple files over the weekend, to match most of the other SymPy modules’ organization. Tests were added for a lot of things; but more are still needed. I’ve tried to write tests for the most basic functionality, and make that functionality more robust.
Something interesting comes up when testing though; frequently, outputs are generated which are equal to the “reference value” in the test file, but they don’t equate to True in the SymPy code. I’ve been trying to make compromises between using expand()/simplify() (actually, I am using trigsimp(), due to the nature of the expressions generated), and getting more complicated expressions to work. The further out you go when creating ReferenceFrames (A is rotated from N, B is rotated from A….), the more complicated the direction cosine matrix between the two frames are. I’ve tried to keep the examples in the test files to what I think is a reasonable limit…. which is somewhat arbitrary, but is based on experience I’ve had with more complicated multibody system. It’s important to note that the expressions generated are still valid; they just don’t compare correctly.
The other big thing was switching to using dictionaries to represent positions, orientations, velocities, etc. By storing a dictionary in each frame of it’s DCM (or ang_vel, or whatever) relative to another frame, AND in that other frame the inverse DCM to this frame, immediate comparisons between the two are simpler. But, it also has the advantage of making it possible to have code of a reasonable length to find the shortest number of intermediate frames between two frames (this is a lot better, and the code is simpler and shorter too). Basically, knowing the start and end frame, lists are made from the start frame to every other frame using the dictionary entries as the next possible steps (with no backtracking). Then, lists that don’t end with the end frame are thrown away. Finally, we take the shortest list. This is nice as it should make the expression as simple as possible. Also, it sets things up so that if the user defines, say, angular velocity between two non-adjacent frames, that this defined angular velocity will be used instead of the auto-generated angular velocity, as it will have a shorter list. That was one important behavior; always use the user defined values over auto-generated ones. That’s why the dictionary has been so helpful; you just update the key: value pair and everything is good. It’s also worked out well for angular velocities, as now they are generated on DCM formation and stored in an intelligent manner, and are overwritten by the user if desired.
So, it looks like the code is more robust now, and can scale to more complicated systems (I hope). Next is better code for velocities & accelerations of points, writing the body & particle classes, then finally starting to implement Kane’s Method as an algorithm to get the equations of motion. Oh, and more tests. And documentation. And getting Sphinx to work. And ….