I have added a constraint in the form of law of cosines as follows:

# Build the kinematic loop constraint (Law of Cosines)
ak_vec = k_pt.pos_from(a_pt)
ak_len = ak_vec.magnitude()
ay_vec = y_pt.pos_from(a_pt)
ay_len = ay_vec.magnitude()
kay_angle = acos((ak_len**2 + ay_len**2 - actuator_len**2)/(2*ak_len*ay_len))

# Orient the arm frame to the ground frame
arm_frame.orient(ground_frame, 'Axis', (kay_angle, ground_frame.z))


This got be a bit farther, however, when I try to calculate the length from 
y to b, it throws (No Connecting Path found between actuator_frame and 
arm_frame):

length_yb = b_pt.pos_from(y_pt).magnitude()


I gave an orientation between ground_frame and arm_frame... why can it not 
go through that path instead since the y_pt exists in both the ground_frame 
and the actuator_frame?

Thanks for the help,
Aaron



On Friday, December 1, 2017 at 10:05:31 AM UTC-6, Jason Moore wrote:
>
> You will need to define an equation that defines the kinematic loop 
> constraint (holonomic constraint). This will look like 0 = f(coordinates, 
> lengths). If you can then solve this equation for the dependent coordinate, 
> then you can construct all of your position vectors in terms of only the 
> independent coordinates, using the solution to the constraint equation to 
> substitute in for the dep coordinate. If you can't analytically solve the 
> loop constraint (often the case), then you need to define all your position 
> vectors in terms of both the independent and dependent coordinates. You can 
> then take the time derivative of f to get a pseudo velocity constraint 
> which you can include as an extra kinematic differential equation. 
> Depending on what you want to do (forward sim, initial value problem, 
> linearization, etc) there are different things to do with this equation.
>
> moorepants.info
> +01 530-601-9791
>
> On Thu, Nov 30, 2017 at 9:14 AM, Aaron Shatters <[email protected] 
> <javascript:>> wrote:
>
>> I have a simple 3 member actuator where one of the members is a linear 
>> actuator.  I have a reference frame for each member (ground, arm, linear 
>> actuator).  I cannot seem to get sympy to use the point locations within 
>> multiple frames to serve as constraints that will determine the relative 
>> frame orientations.  For example, if I have a triangle where each side of 
>> the triangle has its own reference frame, the point positions alone should 
>> be able to determine the frame orientations, but I cannot figure out how to 
>> let sympy know this.  How would I do this? (this generic pattern should 
>> apply to any complex linkage with any number of closed geometries.)
>>
>> I have included code:
>>
>> from sympy import *
>> from sympy.physics.mechanics import dynamicsymbols, ReferenceFrame, Point
>>
>>
>> #
>> # I would like to develop the model for the below picture...
>> #
>> # There is an 'arm' and a linear 'actuator'.
>> #   - the a_pt of the arm is connected to the ground
>> #   - the y_pt of the actuator is connected to the ground
>> #   - the k_pt is on the arm and the actuator is connected to it
>> #
>> # The desire is to solve the relationship between the length of the 
>> actuator (a dynamic symbol)
>> # and the angle from vector AY to AB, as well as the magnitude of the Y-B 
>> vector
>> #
>> # Since a closed path triangle is created between A, K, and Y, we should 
>> be able to 'automagically'
>> # orient the frames with respect to each other, but I don't know how to 
>> do this without introducing
>> # a bunch of dummy dynamic symbols to represent the orientations between 
>> the frames.
>> #
>> #                            O <-- b_pt
>> #                          //
>> #                         //
>> #                  --->  //
>> #                 /     //
>> #              Arm     //
>> #              /       O <-- k_pt
>> #              --->  // \
>> #                   //   \
>> #                  //     \  <-- Actuator (extends/retracts)
>> #                 //       \
>> #                //         \
>> #      a_pt --> O============O <-- y_pt
>> #                 /  /  /  /
>> #                   Ground
>> #
>>
>>
>> # Symbols for the Ground Points
>> ground_coord_a = symbols(('ground_coord_a_x', 'ground_coord_a_y'))
>> ground_coord_y = symbols(('ground_coord_y_x', 'ground_coord_y_y'))
>>
>>
>> # Symbols for the Arm Points
>> arm_coord_a = symbols(('arm_coord_a_x', 'arm_coord_a_y'))
>> arm_coord_k = symbols(('arm_coord_k_x', 'arm_coord_k_y'))
>> arm_coord_b = symbols(('arm_coord_b_x', 'arm_coord_b_y'))
>>
>>
>> # Symbol for the Actuator Cylinder Length
>> actuator_len = dynamicsymbols('actuator_len')
>>
>>
>> # Create the reference frame for each member
>> ground_frame = ReferenceFrame('ground_frame')
>> ground_frame_origin_pt = Point('ground_frame_origin_pt')
>>
>>
>> arm_frame = ReferenceFrame('arm_frame')
>> arm_frame_origin_pt = Point('arm_frame_origin_pt')
>>
>>
>> actuator_frame = ReferenceFrame('actuator_frame')
>>
>>
>> # Define all of the Points on the Linkage
>> a_pt = Point('a_pt')
>> b_pt = Point('b_pt')
>> k_pt = Point('k_pt')
>> y_pt = Point('y_pt')
>>
>>
>> # Place the points on the Ground
>> a_pt.set_pos(ground_frame_origin_pt, ground_coord_a[0] * ground_frame.x + 
>> ground_coord_a[1] * ground_frame.y)
>> y_pt.set_pos(ground_frame_origin_pt, ground_coord_y[0] * ground_frame.x + 
>> ground_coord_y[1] * ground_frame.y)
>>
>>
>> # Place the points on the Arm
>> a_pt.set_pos(arm_frame_origin_pt, arm_coord_a[0] * arm_frame.x + 
>> arm_coord_a[1] * arm_frame.y)
>> b_pt.set_pos(arm_frame_origin_pt, arm_coord_b[0] * arm_frame.x + 
>> arm_coord_b[1] * arm_frame.y)
>> k_pt.set_pos(arm_frame_origin_pt, arm_coord_k[0] * arm_frame.x + 
>> arm_coord_k[1] * arm_frame.y)
>>
>>
>> # Place the points on the Actuator
>> k_pt.set_pos(y_pt, actuator_len * actuator_frame.x + 0.0 * actuator_frame
>> .y)
>>
>>
>> # Of course things work within the same frame
>> length_ab = b_pt.pos_from(a_pt).magnitude()
>> print(length_ab)
>>
>>
>> # How about length Y to K?
>> length_yk = k_pt.pos_from(y_pt).magnitude()
>> print(length_yk)
>>
>>
>> # But not Y to B?
>> try:
>>     length_yb = b_pt.pos_from(y_pt).magnitude()
>>     print(length_yb)
>> except ValueError as e:
>>     print(e)
>>
>>
>> # Ok, I can add a redundant symbol to orient the ground frame to the arm 
>> frame...
>>
>>
>> # Dynamic Symbols (time variant)
>> angle_ground_to_arm = dynamicsymbols('angle_ground_to_arm')
>> arm_frame.orient(ground_frame, 'Axis', (angle_ground_to_arm, ground_frame
>> .z))
>>
>>
>> # Now can I get Y to B?  still no
>> try:
>>     length_yb = b_pt.pos_from(y_pt).magnitude()
>>     print(length_yb)
>> except ValueError as e:
>>     print(e)
>>
>>
>> # Ok, do I need to orient the actuator to the ground as well?
>> angle_ground_to_actuator = dynamicsymbols('angle_ground_to_actuator')
>> actuator_frame.orient(ground_frame, 'Axis', (angle_ground_to_actuator, 
>> ground_frame.z))
>>
>>
>> # Now can I get Y to B?
>> # Yes, but now I have an expression that involves 
>> 'angle_ground_to_actuator(t)' as well as 'actuator_len(t)'
>> #   which is redundant.  I don't actually have to degrees of freedom or 
>> actuators.
>> try:
>>     length_yb = b_pt.pos_from(y_pt).magnitude()
>>     print(length_yb)
>> except ValueError as e:
>>     print(e)
>>
>>
>> # How do I make sympy know about the closed path so that it can 'infer'
>> # the frame orientations based on that closed path?  (Without adding 
>> redundant dummy dynamic symbols)
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "sympy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> To post to this group, send email to [email protected] <javascript:>
>> .
>> Visit this group at https://groups.google.com/group/sympy.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/sympy/639fdd0f-a35c-44ee-b57a-405f622bc205%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/sympy/639fdd0f-a35c-44ee-b57a-405f622bc205%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/d8e9583c-7693-4c93-a36f-6d8d4efc6f51%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to