Lists of bodies and their transforms

We might want to have several distinct bodies. Here, we discuss how to combine bodies into lists, and similarly, their transforms.

using RigidBodyTools
using Plots

Body list

Suppose we have two bodies and we wish to combine them into a single list. The advantage of doing so is that many of the operations we have presented previously also extend to lists. We use BodyList to combine them.

b1 = Circle(1.0,0.02)
b2 = Rectangle(1.0,2.0,0.02)
bl = BodyList([b1,b2])
BodyList(Body[Circular body with 312 points and radius 1.0
   Current position: (0.0,0.0)
   Current angle (rad): 0.0
, Closed polygon with 4 vertices and 600 points
   Current position: (0.0,0.0)
   Current angle (rad): 0.0
])

Another way to do this is to push each one onto the list:

bl = BodyList()
push!(bl,b1)
push!(bl,b2)
2-element Vector{Body}:
 Circular body with 312 points and radius 1.0
   Current position: (0.0,0.0)
   Current angle (rad): 0.0

 Closed polygon with 4 vertices and 600 points
   Current position: (0.0,0.0)
   Current angle (rad): 0.0

We can transform the list by creating a list of transforms with a MotionTransformList

X1 = MotionTransform([2.0,3.0],0.0)
X2 = MotionTransform([-2.0,-0.5],π/4)
tl = MotionTransformList([X1,X2])
MotionTransformList(MotionTransform[2d motion transform, x = [2.0, 3.0], R = [1.0 0.0; -0.0 1.0], 2d motion transform, x = [-2.0, -0.5], R = [0.7071067811865476 0.7071067811865475; -0.7071067811865475 0.7071067811865476]])

The transform list can be applied to the whole body list simply with

tl(bl)
2-element Vector{Body{N, RigidBodyTools.ClosedBody} where N}:
 Circular body with 312 points and radius 1.0
   Current position: (2.0,3.0)
   Current angle (rad): 0.0

 Closed polygon with 4 vertices and 600 points
   Current position: (-2.0,-0.5)
   Current angle (rad): 0.7853981633974483

which creates a copy of the body list and transforms that, or

update_body!(bl,tl)
2-element Vector{Body{N, RigidBodyTools.ClosedBody} where N}:
 Circular body with 312 points and radius 1.0
   Current position: (2.0,3.0)
   Current angle (rad): 0.0

 Closed polygon with 4 vertices and 600 points
   Current position: (-2.0,-0.5)
   Current angle (rad): 0.7853981633974483

which updates each body in bl in place.

Let's see our effect

plot(bl)
Example block output

It is important to note that the list points to the original bodies, so that any change made to the list is reflected in the original bodies, e.g.

plot(b2)
Example block output

Utilities on lists

There are some specific utilities that are helpful for lists. For example, to collect all of the x, y points (the segment midpoints) in the list into two vectors, use

x, y = collect(bl)
([3.0000000000000013, 2.9997972289848516, 2.9991889981715714, 2.9981755542233195, 2.9967573081342116, 2.9949348350626472, 2.9927088740980565, 2.9900803279611665, 2.987050262637916, 2.9836199069471463  …  -1.4272435072388965, -1.4131013716151657, -1.3989592359914347, -1.384817100367704, -1.370674964743973, -1.356532829120242, -1.342390693496511, -1.32824855787278, -1.314106422249049, -1.299964286625318], [3.0, 3.02013705326544, 3.040265940109416, 3.0603784974222856, 3.0804665687167256, 3.100522007435517, 3.120536680255323, 3.1405024703850923, 3.1604112808577587, 3.180255037813904  …  -2.486970055134199, -2.5011121907579295, -2.51525432638166, -2.5293964620053915, -2.543538597629122, -2.5576807332528535, -2.571822868876584, -2.5859650045003155, -2.600107140124046, -2.614249275747777])

In a vector comprising data on these concatenated surface points, we can use view to look at just one body's part and change it:

f = zero(x)
f1 = view(f,bl,1)
f1 .= 1.0;
plot(f)
Example block output

Also, we can sum up the values for one of the bodies:

sum(f,bl,2)
0.0

Body and transform list functions

RigidBodyTools.getrangeFunction
getrange(bl::BodyList,bid::Int) -> Range

Return the subrange of indices in the global set of surface point data corresponding to body bid in a BodyList bl.

source
getrange(ls::RigidBodyMotion,dimfcn::Function,jid::Int) -> Range

Return the subrange of indices in the global state vector for the state corresponding to joint jid in linked system ls.

source
Base.collectMethod
collect(bl::bodylist[,endpoints=false][,ref=false]) -> Vector{Float64}, Vector{Float64}

Collect the inertial-space coordinates of all of the Lagrange points comprising the bodies in body list bl and return each assembled set of coordinates as a vector. By default, endpoints=false and ref=false, which means this collects the midpoints of segments in the inertial coordinates. If endpoints=true it collects segment endpoints instead. If ref=true it collects the coordinates in the body coordinate system.

source
Base.sumMethod
sum(f::AbstractVector,bl::BodyList,i::Int) -> Real

Compute a sum of the elements of vector f corresponding to body i in body list bl.

source
Base.viewMethod
view(f::AbstractVector,bl::BodyList,bid::Int) -> SubArray

Provide a view of the range of values in vector f corresponding to the Lagrange points of the body with index bid in a BodyList bl.

source

This page was generated using Literate.jl.