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.
