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)

get_inertias()[source]
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)

symbols()[source]

Return the free symbols for the equations of motion.

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)

skydy.multibody.MultiBody.latexify(string_item)[source]

Recursive function to turn a string, or sympy.latex to a latex equation.

Parameters

string_item (str) – string we want to make into an equation

Returns

a latex-able equation.

Return type

equation_item (str)

Module contents