skydy.connectors package

Submodules

skydy.connectors.Connection module

class skydy.connectors.Connection.Connection(body_in, joint, body_out)[source]

Bases: object

__init__(body_in, joint, body_out)[source]

Define the connection fo two bodies, through a joint.

The rigour of this definition lies in the Joint. Refer to that object to correctly define that object, in order to easily define this object.

The main consideration is that the body_in argument must align with Joint’s body_in_coord, and the body_out argument must relate to the Joint’s body_out_coord.

Parameters
  • body_in (Body) – the input body

  • joint (Joint) – the joint, defined as a common location for the input and output bodies, and the associated DOFs. Note, it is critical here, that the joint’s input coordinate is in body_in coordinate frame, and the output coordinate is in body_out coordinate frame.

  • body_in – the output body

Returns

None

Examples

>>> from skydy.connectors import DOF, Connection, Joint
>>> from skydy.rigidbody import Body, BodyCoordinate, Ground
>>> # Two point-masses that meet at the origin
>>> p0 = BodyCoordinate("O")
>>> p1 = BodyCoordinate("G/O", 0, 0, 0)
>>> # Assume the joint can move in the x-coordinate
>>> j1 = Joint(p0, p1, [DOF(0)])
>>> # Define the two bodies
>>> b1 = Body()
>>> b2 = Body()
>>> # Define the connection
>>> cnx = Connection(b1, j1, b2)
as_dict()[source]

Return a dictionary of the coordinate and properties of the connection.

property body_in
property body_out
draw(ax=None, sub_vals=None)[source]

Draw the connection

Parameters
  • ax (matplotlib.axes._subplots.AxesSubplot) – the axis to plot the connection on.

  • sub_vals (dict) – symbol-value pairs required to go from symbolic to numeric expression. It is important to note, that all symbols each body is dependent on, for example, for upstream bodies and joints, are included.

Returns

updated axes, with plots.

Return type

ax (matplotlib.axes._subplots.AxesSubplot)

Example

>>> import matplotlib.pyplot as plt
>>> from skydy.connectors import DOF, Connection, Joint
>>> from skydy.rigidbody import Body, BodyCoordinate, Ground
>>> # Two point-masses that meet at the origin
>>> p0 = BodyCoordinate("O")
>>> p1 = BodyCoordinate("G/O", 0, 0, 0)
>>> # Assume the joint can move in the x-coordinate
>>> j1 = Joint(p0, p1, [DOF(0)], "J")
>>> # Define the two bodies
>>> b1 = Body()
>>> b2 = Body()
>>> # Define the connection
>>> cnx = Connection(b1, j1, b2)
>>> # Define the axes
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111, projection='3d')
>>> ax = cnx.draw(ax)
>>> plt.show()
global_configuration()[source]

Propagate the configuration from the input body, to the output body through the joint.

Updates the attribute values in place.

Diagram:

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀z2⠀⠀⠀⠀y2
⠀⠀z1⠀⠀y1⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀/
⠀⠀⠀|⠀⠀/⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀p_j⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀/
⠀⠀⠀|⠀/⠀⠀⠀⠀⠀_____—->X—–_____⠀⠀⠀⠀/
⠀⠀⠀|/….—-⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀—–>O2—-x2
⠀⠀⠀O1——-x1⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀^G2
⠀⠀⠀^G1
Thus,
p_O2 = r1 + R1 * (P_J/O1 + r2 + R2 * P_O2/J) = p_in + p_j_in + add_dof + p_out_j,
where
p_in: Global coordinate of COM of input link.
p_j_in: Rotated position of joint on input link.
p_out_j: Relative position of COM in global frame of output link wrt joint.
add_dof: Additional DOFs from joint, in the input link’s coordinate Frame.
property joint

skydy.connectors.DOF module

class skydy.connectors.DOF.DOF(idx, free=True, const_value=0)[source]

Bases: object

__init__(idx, free=True, const_value=0)[source]

A Degree of Freedom is nothing other than a body coordinate that is able to move.

Thus, to define a DOF, we need to simply supply the free index (idx). By default, if it is free, there is no constant value, so we do not need to supply the second, or third arguments.

Parameters
  • idx (int) – the free coordinate index, between 0 and 5.

  • free (bool) – if the coordinte at index idx is free. True by default.

  • const_value (int or float) – If the DOF is not free, i.e., free=False on instantiation, we assign the constant value the coordinate has. By defualt this is zero.

Returns

None

Example

Demonstrate all combinations of the DOF construction.

>>> from skydy.connectors import DOF
>>> # Define a DOF in the x-coordinate
>>> x_dof = DOF(0)
>>> # Note the following ALSO defines a coordinate in the y-direction
>>> y_dof = DOF(1, True)
>>> # Define a constraint in the z-direction, at a value of 10.
>>> z_con = DOF(1, False, 10)
>>> # Define a constraint in the theta_z-direction, at a value of 2.
>>> theta_z_con = DOF(5, False, 2)
property const_value
property free
property idx

skydy.connectors.Joint module

class skydy.connectors.Joint.Joint(body_in_coord, body_out_coord, dof=None, name=None)[source]

Bases: object

__init__(body_in_coord, body_out_coord, dof=None, name=None)[source]

A Joint a common location for two bodies to interact, and how the bodies can move relative to each other, based on the DOFs or constraints a joint has.

A Joint needs to be defined in the inputs AND output body’s coordinate frames.

By default, a joint is assumed to be free in all directions. If a user defines a free or non-free DOF, we account for it. Any unspecified coordintes indices are assumed to be constrained at a value of zero.

Diagram:

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀z2⠀⠀⠀y2
⠀⠀z1⠀⠀y1⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀/
⠀⠀⠀|⠀⠀/⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀p_j⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀/
⠀⠀⠀|⠀/⠀⠀⠀⠀⠀_____—->X—–_____⠀⠀⠀⠀/
⠀⠀⠀|/….—-⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀—–>O2—-x2
⠀⠀⠀O1——-x1⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀^G2
⠀⠀⠀^G1
Let:
- Body 1 have CoM at O1, position r1, and orientation R1;
- Body 2 have CoM at O2, position r2, and orientation R2;
- suppose a there is a Joint at the point p_j.
Then, the point p_j can be described in both Body 1 and Body 2’s coordinate frames, and given by:
- body_in_coord (Body 1) is the vector from O1 -> p_j in (x1, y1, z1), designated P_J/O1;
- body_out_coord (Body 2), is the vector from p_j -> O2 in (x2, y2, z2), designated P_O2/J.

The degrees of freedom are defined as motion in the input Body’s coordinate frame, and is equivalent to the body position of r2 and orientation R2, with the joint DOFs applied to this body’s coordinates.

This means that with knowledge of the input body position and orientation, DOFs, and the two vectors O1 -> p_j and p_j -> O2, the global position and orientation of the output is defined by

p_O2 = p_O1 + R1 * (P_J/O1 + P_J/dof + R2 * P_O2/J),
p_O2 = r1 + R1 * (P_J/O1 + r2 + R2 * P_O2/J).

Note, these are exactly the calculations that are done by the Connection object when calculating the global configuration.

Parameters
  • body_in_coord (BodyCoordinate) – the location of the joint in the input body’s coordinate frame.

  • body_out_coord (BodyCoordinate) – the location of the joint in the output body’s coordinate frame.

  • dof (list(DOF), or None) – the list of DOFs for the joint. By default, all coordinates are free.

  • name (int or str) – the name of the joint.

Returns

None

Example

>>> from skydy.connectors import DOF
>>> from skydy.rigidbody import BodyCoordinate
>>> # Define the location of the joint in the input coordinate frame
>>> p_1 = BodyCoordinate(1, 10, 4, 5)
>>> # Define the location of the joint in the output coordinate frame
>>> p_2 = BodyCoordinate(2, -5, -3, -2)
>>> # Define the DOFs for our joint. Say x-direction and
>>> # theta_y directions
>>> j_dofs = [DOF(0), DOF(4)]
>>> # Define the joint
>>> joint = Joint(p_1, p_2, j_dofs, "J")
>>> # Check which DOFs are free. Expect 0 and 4.
>>> for dof in joint.dof:
>>>     if dof.free:
>>>         print(dof.idx)
property body_in_coord
property body_out_coord
property dof
id_counter = 0

Module contents