skydy.multibody package¶
Submodules¶
skydy.multibody.MultiBody module¶
- class skydy.multibody.MultiBody.MultiBody(connections=None, name=None)[source]¶
Bases:
object- __del__()[source]¶
Overwrite destructor to remove MultiBody name from list, and decrease the MultuBody counter.
- __init__(connections=None, name=None)[source]¶
A MultiBody is a sequence of Connections. If we are diligent with our definitions of coordinates, bodies and joints, the creation of MultiBody object is straightforward.
The most important Connection is the first one, as this is the connection that relates our MultiBody object to the Ground. All other Connections are then related to Body’s that are defined in upstream, or earlier connections.
- Parameters
connections (list(Connections)) – a list of Connection objects. The first Connection in this list must reference the Ground.
name (str or int) – the name of the MultiBody. Note, we do not allow duplicate MultiBody names.
- Returns
None
Example
Define a MultiBody with one connections.
>>> from skydy.rigidbody import Body, BodyCoordinate, BodyForce, BodyTorque, Ground, GroundCoordinate >>> from skydy.connectors import Connectors, DOF, Joint >>> # Let's define a MultiBody (car) that moves in the x-direction only >>> # Provide some dimensions >>> l_car, w_car, h_car = 2, 1, 1 >>> car_name = "1" >>> # Define the body >>> b_car = Body(car_name) >>> # Instantiate the car's dimensions >>> b_car.dims.assign_values([l_car, w_car, h_car]) >>> # Add force to car in the car's x-coordinaate. >>> F1 = BodyForce(name="1", x_dir=True) >>> # Force is applied at the COM >>> force_loc = BodyCoordinate("PF1", 0, 0, 0) >>> # Add the force at the location >>> b_car.add_force(F1, force_loc) >>> # Instantiate the ground >>> b_gnd = Ground() >>> p_gnd = GroundCoordinate() >>> # Location of car wrt ground >>> p_car = BodyCoordinate("G1/O", 0, 0, 0) >>> # Degrees of freedom >>> car_dofs = [DOF(0)] >>> # Ground to car joint >>> j1 = Joint(p_gnd, p_car, car_dofs, name=p_gnd.name) >>> # The connection of the bodies through the joint >>> cnx_car = Connection(b_gnd, j1, b_car) >>> # The multibody object >>> oned_car = MultiBody([cnx_car], "car")
- add_connection(connection)[source]¶
Add a connection to the MultiBody
- Parameters
connection (Connection) – a connection we want to to add.
- Returns
None
- as_latex(linearized=False, output_dir=None, file_name=None, include_diag=True)[source]¶
Generate the latex and pdf document deriving the equations of motion of the MultiBody object. Uses the skydy.output.LatexDocument object.
- Parameters
linearized (bool) – display the linear or nonlinear system matrices
output_dir (str or None) – location to generate the .tex and .pdf outputs.
file_name (str or None) – name for the .tex and .pdf files.
include_diag (bool) – include the matplotlib generated diagram of the mutlibody.
- Returns
None.
- property connections¶
- controllable(linear=True, max_iters=100)[source]¶
Determine if is Controllable or Small Time Locally Accessible (STLA).
For a linear system of the form x’ = Ax + Bu, this is if the Controllability Gramian C = [B AB … A^(n-1)B] has dimension N, where N is the number of states.
For a nonlinear system of the form x’ = f0 + f(x, u), this is if the span of Lie brackets has dimension N, where N is the dimension of the configuration space.
The Lie bracket of two vectors f and g, [f, g] = (df/dx)g - (dg/dx)f.
- Parameters
linear (bool) – determine controllability for the linearized system. Default is True.
max_iters (int) – maximum number of iterations for the Lie Bracket.
- Returns
if the system is Controllable (linear), or Small Time Locally Accessible (nonlinear), as per the definitions above.
- Return type
controllable (true)
- draw(output_dir=None, save_fig=True)[source]¶
Draw the MultiBody object. Uses the Body and Connection draw methods.
- Parameters
output_dir (str or None) – location to generate the .tex and .pdf outputs.
save_fig (bool) – save or simply render the drawing.
- eoms()[source]¶
return the LHS and RHS of the equations of motion,
The LHS is the Riemannian Metric times the accelerations. The RHS is the Generalised Forces minus the potential functions, less any other dissipative forces.
- force_symbols()[source]¶
Returns the force symbols. We have to remove the coordinates and time symbols.
- get_configuration()[source]¶
Print the configuration, coordinates, dimensions of the bodies in the MultiBody object.
- get_dimensions()[source]¶
Get all the dimensions associated with the MultiBody, from each body and Joint coordinates.
- get_equilibria(unforced=True)[source]¶
Get the equilibria configurations for the MultiBody.
Equilibria exist at configurations when the velocities and accelerations are zero. They can be forced or unforced.
- For a system with EOMs of the form:
x’’ = f(x, x’, u)
- The unforced equlibria are the x0 such that
f(x0, 0, 0) = 0.
- The forced equilibria, x0, u0, satisfy
f(x0, 0, u0) = 0.
- Parameters
unforced (bool) – returns the forced or unforced equilbria
- Returns
the coordinate equilibria values. force_eum (sympy.matrix): the force equilibria values
- Return type
coord_eum (sympy.matrix)
- id_counter = 0¶
- id_names = []¶
- is_stable()[source]¶
Determine if a configuration around a certain equilibria is stable, as defined by the values of the poles of the Linearized sytem evaluated at each equilbrium.
- Parameters
self –
- Returns
a list of [eum, stable] pairs, where eum is the equilibrium values and stable if that system is stable in that configuration.
- Return type
stable_eum (list)
- poles(evaluate=False)[source]¶
Get the open loop poles of the Linearized system.
This is just the eigenvalues of linearized state transition matrix, A, at an equilibrium condition.
We need the intertial properties on the RHS, with the A matrix.
- Parameters
evaluate (True) – whether to substitute the dimension and inertial values in. Prevents overloy complex expressions and thus, long calcultion times.
- Returns
k-v pairs are eigenvalues of the linearlised A matrices and multiplicity.
- Return type
eig_A (dict)
- system_matrices(linearized=False, m_on_lhs=True)[source]¶
Returns the linear or non-linear system matrices.
Assume the MultiBody state x = (q, dq), where q are the generalised coordintae, and dq the associated velocities.
Then the system is described by:
M * x’ = f(x, u),
where M is a block matrix with diagonal entries of the Identity and the Riemannian metric, i.e., M = blockdiag(I, G)
The linear system matrices are then defined by:
M * x’ = A * x + B * u
where A = d/dx(f(x, u)), and B = d/du(f(x, u)).
To avoid overly complex expressions, we keep the M matrix on the LHS.
If you would like the systems returned with M not on the LHS, make m_on_lhs=False, and you will get x’ = M^(-1) * f(x, u), x’ = M^(-1) * (A * x + B * u).
- Parameters
linearized (bool) – Return the linearized (or linear state-space) representation of the system, or nonlinear.
m_on_lhs (bool) – if we want the inertial properties on the LHS, with the accelerations, or on the RHS with the states. The RHS requires the inverse of the M matrix to be taken, meaning it can get messy, quickly.
- Returns
the linear or nonlinear state transitions matrix. B (sympy.matrix): the linear input matrix. If linearized=False, this is just the appropriately sized zero matrix.
- Return type
A (sympy.matrix)