I am trying to use DirectTranscription
and DirectCollocation
to find the optimal trajectory in SO(3) for a free-floating box i.e. rotating a satellite from one pose to another. To start with, I'm using the Example 6.12: Reorientation of a Rigid Body from Betts, J. T. (2010). Practical Methods for Optimal Control and Estimation Using Nonlinear Programming.
Here, the body inertia is given as Ixx = 5621, Iyy = 4547, Izz = 2364. I've made a simple box.urdf with these inertias.
The initial rotation quaternion is [1,0,0,0] and the final rotation quaternion is [cos(phi/2),sin(phi/2),0,0] (phi being 150deg) with the initial and final rotation velocities being zero. The position and its derivative are set as zero for initial and final states.
As this is basically a double integrator problem in multiple axes in SO(3), the optimal trajectory is a bang-bang controller.
I am using the get_applied_generalized_force_input_port()
of the MultibodyPlant for the actuation (u) and hence this port index is used to initialize the trajectory optimization.
In both, DirectTransciption
and DirectCollocation
, the optimization fails but for different reasons:
DirectTransciption
: This fails due to infeasible constraints. But the same constraints seems to work forDirectCollocation
as that gives another error. The code snippet used:
NDirTrans = 300
prog = DirectTranscription(plant_d, trajOptContext, NDirTrans,
input_port_index=plant_d.get_applied_generalized_force_input_port().get_index())
prog.AddBoundingBoxConstraint(x0, x0, prog.initial_state())
prog.AddBoundingBoxConstraint(xf, xf, prog.final_state())
for u_index in range(prog.input().size):
prog.AddConstraintToAllKnotPoints(prog.input()[u_index] <= 50)
prog.AddConstraintToAllKnotPoints(prog.input()[u_index] >= 50)
result = Solve(prog)
DirectCollocation
: This fails due to the following error:
RuntimeError: Encountered singular articulated body hinge inertia for body node index 1.
Please ensure that this body has non-zero inertia along all axes of motion.
I verify that the body at node index 1 does have inertia parameters along all the axes and hence I'm stuck here.
A google colab script to reproduce the errors can be seen here. It is not needed to run the program to see the errors as the cell outputs are saved and can be viewed without running the program. This includes viewing the Spatial Inertia matrix for Body with Node Index 1.