def DiscreteFiniteHorizonLQR(system,
                             X0,
                             DT,
                             Q=None,
                             R=None,
                             tol=1e-6,
                             steps=1000,
                             Pk=None):
    mvi = trep.MidpointVI(system)
    dsys = discopt.DSystem(mvi, [0, DT])
    # create an A and B:
    Xt = np.vstack((X0, X0))
    Ut = np.array([X0[2:4]])
    A, B = dsys.linearize_trajectory(Xt, Ut)
    A = A[0]
    B = B[0]
    # now we can start solving Riccati equation:
    if Pk is None:
        Pk = Q
    Pkp1 = 1000 * Pk
    err = True
    for i in range(steps):
        Pkp1 = Q + MM(A.T, Pk, A) - MM(A.T, Pk, B,
                                       np.linalg.inv(
                                           (R + MM(B.T, Pk, B))), B.T, Pk, A)
        if np.linalg.norm(Pkp1 - Pk, ord=2) < tol:
            err = False
            break
        Pk = Pkp1
    # calc K
    K = MM(np.linalg.inv(R + MM(B.T, Pk, B)), B.T, Pk, A)
    return err, K, Pk
def LQROptimizer(system, X0, DT, Q=None, R=None, tol=1e-6, steps=1000):
    """
    This class takes a system, an equilibrium state, a timestep, weighting
    matrices, an error tolerance. It then solves a discrete-time LQR problem
    to build a feedback regulator about the equilibrium point.
    """
    # first let's build an MVI and dsystem
    mvi = trep.MidpointVI(system)
    tvec = np.arange(0.0, steps * DT, DT)  #np.array([0, DT])
    dsys = discopt.DSystem(mvi, tvec)

    # build reference trajectory:
    Xd = np.array([X0] * len(tvec))
    Ud = np.array([X0[system.nQd:system.nQ]] * (len(tvec) - 1))

    # build cost matrices:
    if Q is None: Q = np.identity(dsys.nX)
    if R is None: R = np.identity(dsys.nU)
    Qk = lambda k: Q
    Rk = lambda k: R

    (Kstab, A, B) = dsys.calc_feedback_controller(Xd,
                                                  Ud,
                                                  Qk,
                                                  Rk,
                                                  return_linearization=True)
    err = False
    if np.linalg.norm(Kstab[0] - Kstab[1], ord=2) > tol:
        rospy.logwarn("LQR stabilizing controller not settled!")
        err = True
    return err, Kstab[0]
def main():
    # first let's build a system:
    sys = DeltaRobotTrep(L_base, L_platform, R_base, R_platform)

    dt = 0.05
    tf = 10.0

    # setup initial conditions
    _ = sys.forward(*(-0.2 * np.ones(3)))
    _ = sys.inverse(0.0, 0.0, 1.2)
    q0 = sys.q

    # add external force:
    trep.forces.BodyWrench(sys, sys.platform_center,
                           (0, 0, "external_z", 0, 0, 0))

    def f_func(t):
        if t > 3.0:
            return 50
        else:
            return 0
        # amp = 20
        # period = 1.0
        # return amp*np.sin(t*2*pi/period) + 40

    mvi = trep.MidpointVI(sys)
    mvi.initialize_from_configs(0.0, q0, dt, q0)
    q = [mvi.q2]
    t = [mvi.t2]
    while mvi.t1 < tf:
        mvi.step(mvi.t2 + dt, u1=[f_func(mvi.t2)])
        q.append(mvi.q2)
        t.append(mvi.t2)
    sys = DeltaRobotTrep(L_base, L_platform, R_base, R_platform)
    visual.visualize_3d([visual.VisualItem3D(sys, t, q)])
Beispiel #4
0
def simulate_system(system):

    system.satisfy_constraints(tolerance=1e-1, keep_kinematic=True)
    q0 = system.q
    tcur = 0.0

    mvi = trep.MidpointVI(system)
    mvi.initialize_from_configs(tcur, q0, dt, q0)

    T = [mvi.t1]
    Q = [mvi.q1]
    steps = 0

    while mvi.t1 < tf:
        #         system.satisfy_constraints(tolerance=1e-1, keep_kinematic=True)
        #         if mvi.t1 < (400*click):
        #             u = tuple([-19*kt, 19*kt])
        #         else:
        #             u = tuple([0,0])

        u = tuple([0 * kt, 0 * kt])
        mvi.step(mvi.t2 + dt, u, (), 5000)
        T.append(mvi.t1)
        Q.append(mvi.q1)
        steps = steps + 1

    # while tcur < tf
    # stance for 100 clicks

    # flight

    # make sure tf is ~0.2 s

    return (T, Q)
def simulate_system(system):
    """
    Simulates the system from its current configuration with no
    initial velocity for the duration and time step specified by global variables.
    """
    # Extract the current configuration into a tuple to use as the two
    # initial configurations of the variational integrator.
    q0 = system.q

    # Create and initialize the variational integrator.
    mvi = trep.MidpointVI(system)
    mvi.initialize_from_configs(0.0, q0, dt, q0)

    # Run the simulation and save the results into the lists 't' and 'q'.
    q = [mvi.q1]
    t = [mvi.t1]
    while mvi.t1 < tf:
        mvi.step(mvi.t2 + dt)
        q.append(mvi.q1)
        t.append(mvi.t1)
        # Print out progress during the simulation.
        if abs(mvi.t1 - round(mvi.t1)) < dt / 2.0:
            print "t =", mvi.t1

    return (t, q)
Beispiel #6
0
def simulate_system(system, motor_angles):

    system.satisfy_constraints(tolerance=1e-1, keep_kinematic=True)
    q0 = system.q
    tcur = 0.0

    mvi = trep.MidpointVI(system)
    mvi.initialize_from_configs(tcur, q0, dt, q0)

    T = [mvi.t1]
    Q = [mvi.q1]
    steps = 0

    while mvi.t1 < tf:
        system.satisfy_constraints(tolerance=1e-1, keep_kinematic=True)
        mvi.step(mvi.t2 + dt, tuple([0, 0]), tuple(motor_angles[steps, :]),
                 5000)
        T.append(mvi.t1)
        Q.append(mvi.q1)
        steps = steps + 1

        # TODO: determine force necessary to make the change specified by the change in motor angles
        # TODO: make motor1 a kinematic variable, that can be determined from system dynamics?

    return (T, Q)
def main(links, dt, tf, generalized_method, hybrid_wrenched):
    # Create the system and integrator
    system = make_pendulum(links, hybrid_wrenched)
    mvi = trep.MidpointVI(system)

    # Generate a reference trajectory
    (t_ref, q_ref, u_ref) = generate_reference(mvi, dt, tf)
    write_csv('ref.csv', t_ref, u_ref)

    # Uncomment to display the reference trajectory
    #visualize(system, t_ref, q_ref, u_ref)

    # Perform inverse dynamics
    if generalized_method:
        (t_sol, u_sol) = inverse_dynamics_generalized(mvi, t_ref, q_ref)
    else:
        (t_sol, u_sol) = inverse_dynamics_specialized(mvi, t_ref, q_ref)

    write_csv('sol.csv', t_sol, u_sol)

    # Simulate the system with the new inputs
    (t, q, u) = simulate_system(mvi, t_sol, u_sol, q_ref[0], q_ref[1])

    # Uncomment to display the reconstructed trajectory
    #visualize(system, t, q, u)

    verify_solution(q_ref, q)
 def __init__(self, *args, **kwargs):
     self.sys = kwargs.pop('sys', None)
     if self.sys == None:
         print "Must give trep system as kwarg!"
         return
     super(VI_EKF, self).__init__(*args, **kwargs)
     self.mvi = trep.MidpointVI(self.sys)
     self.dsys = discopt.DSystem(self.mvi, array([0, self.Dt]))
 def __init__(self, system, t, beta=0.7, tolerance=1e-1, DT=None):
     # create a VI
     self.mvi = trep.MidpointVI(system)
     # create a dsys object:
     self.dsys = discopt.DSystem(self.mvi, t)
     # set default optimization props:
     self.beta = beta
     self.tolerance = tolerance
     if DT:
         self.DT = DT
     else:
         self.DT = t[1] - t[0]
     # setup parameters for estimating whether we have time to take a step:
     N = 3
     self.tsamps = deque([self.DT / 3.0] * N, maxlen=N)
     self.coeffs = [2, 4, 10]
def create_system(joint_forces=False, string_forces=False,
                  string_constraints=False, config_trajectory=False):
    # Creates the mechanical system, variational integrator, and discrete system
    # Creates a desired trajectory suitable for the mechanical system from the ik data

    system = Puppet(joint_forces=joint_forces,
                                 string_forces=string_forces,
                                 string_constraints=string_constraints)

    if not os.path.isfile('puppet-desired.mat'):
        generate_desired_trajectory()        

    (t,Qd,p,v,u,rho) = trep.load_trajectory('puppet-desired.mat', system)
    # Disregard all data except t,Q
    dsys = discopt.DSystem(trep.MidpointVI(system), t)
    xid = dsys.build_trajectory(Qd)

    return dsys, xid
Beispiel #11
0
def generate_vi_sim(system, q0):
    # Create and initialize the variational integrator
    mvi = trep.MidpointVI(system)
    mvi.initialize_from_configs(0.0, q0, dt, q0)

    # This is our simulation loop.  We save the results in two lists.
    q = [mvi.q2]
    t = [mvi.t2]
    while mvi.t1 < tf:
        qk2 = qk_func(system, mvi.t2)
        try:
            mvi.step(mvi.t2 + dt, (), qk2)
        except trep.ConvergenceError:
            print "VI integration failed at", mvi.t2 + dt, "seconds"
            break
        q.append(mvi.q2)
        t.append(mvi.t2)
    return t, q
Beispiel #12
0
def simulate_system(system):
    # Now we'll extract the current configuration into a tuple to use as
    # initial conditions for a variational integrator.
    q0 = system.q

    # Create and initialize the variational integrator
    mvi = trep.MidpointVI(system)
    mvi.initialize_from_configs(0.0, q0, dt, q0)

    # This is our simulation loop.  We save the results in two lists.
    q = [mvi.q2]
    t = [mvi.t2]
    while mvi.t1 < tf:
        mvi.step(mvi.t2 + dt)
        q.append(mvi.q2)
        t.append(mvi.t2)

    return (t, q)
def generate_desired_trajectory():
    puppet = trep.puppets.Puppet(joint_forces=False, string_forces=False,
                                 string_constraints=True)


    puppet.q = {
        'torso_rx' : -0.05,
        #'torso_ry' : 0.1,
        'torso_tz' : 0.0,
        'lelbow_rx' : 1.57,
        'relbow_rx' : 1.57,
        'lhip_rx' : pi/2 - 0.6,
        'rhip_rx' : pi/2 - 0.6,
        'lknee_rx' : -pi/2 + 0.6,
        'rknee_rx' : -pi/2 + 0.6,
        ## 'Left Arm String' : 15.4,
        ## 'Right Arm String' : 15.4,
        ## 'Left Leg String' : 16.6,
        ## 'Right Leg String' : 16.6
        }
    puppet.project_string_controls()

    q0 = puppet.q
    u0 = tuple([0.0]*len(puppet.inputs))
    qk2_0 = puppet.qk
    dt = 0.01
    # Create and initialize a variational integrator for the system.
    mvi = trep.MidpointVI(puppet)
    mvi.initialize_from_configs(0.0, q0, dt, q0)

    #print qk2

    left_leg_index = puppet.get_config('left_leg_string-length').k_index
    right_leg_index = puppet.get_config('right_leg_string-length').k_index
    left_arm_index = puppet.get_config('left_arm_string-length').k_index
    right_arm_index = puppet.get_config('right_arm_string-length').k_index


    def calc_vk():
        v2 = [(q2-q1)/(mvi.t2 - mvi.t1) for (q2, q1) in zip(mvi.q2, mvi.q1)]
        v2 = v2[len(puppet.dyn_configs):]
        return v2

    q = [mvi.q2]
    p = [mvi.p2]
    v = [calc_vk()]
    rho = []
    t = [mvi.t2]
    while mvi.t1 < 10.0:
        # For our kinematic inputs, we first copy our starting position.
        qk2 = list(qk2_0) 
        # Now we want to move some of the strings up and down.
        qk2[left_leg_index] += -0.1*sin(0.6*pi*mvi.t1)
        qk2[right_leg_index] += 0.1*sin(0.6*pi*mvi.t1)
        qk2[left_arm_index] += 0.1*sin(0.6*pi*mvi.t1)
        qk2[right_arm_index] += -0.1*sin(0.6*pi*mvi.t1)
        qk2 = tuple(qk2)
        rho.append(qk2)

        mvi.step(mvi.t2+dt, u0, qk2)
        q.append(mvi.q2)
        p.append(mvi.p2)
        v.append(calc_vk())
        t.append(mvi.t2)
        # The puppet can take a while to simulate, so print out the time
        # occasionally to indicate our progress.
        if abs(mvi.t2 - round(mvi.t2)) < dt/2.0:
            print "t =",mvi.t2


    t = np.array(t)
    q = np.array(q)
    p = np.array(p)
    v = np.array(v)
    rho = np.array(rho)

    trep.system.save_trajectory('puppet-desired.mat',
                                puppet, t, q, p, v, None, rho)    
Beispiel #14
0
def QuadMain():

    quadcm_m = 1.0
    quadmotor_m = 1.0
    ball_m = 2.5

    dt = 0.01  # timestep set to 10ms

    # Create a new trep system - 6 generalized coordinates for quadrotor: x,y,z,roll,pitch,yaw
    system = trep.System()
    trep.potentials.Gravity(system, name="Gravity")

    quadz = trep.Frame(system.world_frame, trep.TZ, "quadz")
    quady = trep.Frame(quadz, trep.TY, "quady")
    quadx = trep.Frame(quady, trep.TX, "quadx")

    quadrx = trep.Frame(quadx, trep.RX, "quadrx", kinematic=True)
    quadry = trep.Frame(quadrx, trep.RY, "quadry", kinematic=True)
    # quadrz = trep.Frame(quadry,trep.RZ,"quadrz")
    quadx.set_mass(quadcm_m)  # central point mass

    #    # define motor positions and mass
    #    quad1 = trep.Frame(quadrz,trep.CONST_SE3,((1,0,0),(0,1,0),(0,0,1),(3,0,0)),"quad1")
    #    quad1.set_mass(quadmotor_m)
    #    quad2 = trep.Frame(quadrz,trep.CONST_SE3,((1,0,0),(0,1,0),(0,0,1),(-3,0,0)),"quad2")
    #    quad2.set_mass(quadmotor_m)
    #    quad3 = trep.Frame(quadrz,trep.CONST_SE3,((1,0,0),(0,1,0),(0,0,1),(0,3,0)),"quad3")
    #    quad3.set_mass(quadmotor_m)
    #    quad4 = trep.Frame(quadrz,trep.CONST_SE3,((1,0,0),(0,1,0),(0,0,1),(0,-3,0)),"quad4")
    #    quad4.set_mass(quadmotor_m)

    # define ball frame
    ballrx = trep.Frame(quadx, trep.RX, "ballrx", kinematic=False)
    ballry = trep.Frame(ballrx, trep.RY, "ballry", kinematic=False)
    ball = trep.Frame(ballry, trep.CONST_SE3,
                      ((1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, -1)), "ballcm")
    ball.set_mass(ball_m)

    # set thrust vector with input u1
    trep.forces.BodyWrench(system,
                           quadry, (0, 0, 'u1', 0, 0, 0),
                           name='wrench1')

    #    # set four thrust vectors with inputs u1,u2,u3,u4
    #    trep.forces.BodyWrench(system,quad1,(0,0,'u1',0,0,0),name='wrench1')
    #    trep.forces.BodyWrench(system,quad2,(0,0,'u2',0,0,0),name='wrench2')
    #    trep.forces.BodyWrench(system,quad3,(0,0,'u3',0,0,0),name='wrench3')
    #    trep.forces.BodyWrench(system,quad4,(0,0,'u4',0,0,0),name='wrench4')

    # set quadrotor initial altitude at 3m
    system.get_config("quadz").q = 3.0

    # Now we'll extract the current configuration into a tuple to use as
    # initial conditions for a variational integrator.
    q0 = system.q

    # Create and initialize the variational integrator
    mvi = trep.MidpointVI(system)
    mvi.initialize_from_configs(0.0, q0, dt, q0)

    # These are our simulation variables.
    q = mvi.q2
    t = mvi.t2
    #    u0=tuple([(4*quadmotor_m+quadcm_m+ball_m)/4*9.8,(4*quadmotor_m+quadcm_m+ball_m)/4*9.8,(4*quadmotor_m+quadcm_m+ball_m)/4*9.8,(4*quadmotor_m+quadcm_m+ball_m)/4*9.8])
    #    u=[u0]

    u0 = np.array([(quadcm_m + ball_m) * 9.8])
    u = tuple(u0)

    # start ROS node to broadcast transforms to rviz
    rospy.init_node('quad_simulator')
    broadcaster = tf.TransformBroadcaster()
    pub = rospy.Publisher('config', Float32MultiArray)
    statepub = rospy.Publisher('joint_states', JointState)

    jointstates = JointState()
    configs = Float32MultiArray()

    # subscribe to joystick topic from joy_node
    rospy.Subscriber("joy", Joy, joycall)

    r = rospy.Rate(100)  # simulation rate set to 100Hz

    # PD control variables
    P = 200
    D = 20

    # Simulator Loop
    while not rospy.is_shutdown():

        # reset simulator if trigger pressed
        if buttons[0] == 1:
            mvi.initialize_from_configs(0.0, q0, dt, q0)

#        # calculate thrust inputs
#        u1 = u0[0] + P*(q[4]+0.1*axis[0]) + D*system.configs[4].dq - P*(q[0]-3.0) - D*system.configs[0].dq
#        u2 = u0[1] - P*(q[4]+0.1*axis[0]) - D*system.configs[4].dq - P*(q[0]-3.0) - D*system.configs[0].dq
#        u3 = u0[2] - P*(q[3]+0.1*axis[1]) - D*system.configs[3].dq - P*(q[0]-3.0) - D*system.configs[0].dq
#        u4 = u0[3] + P*(q[3]+0.1*axis[1]) + D*system.configs[3].dq - P*(q[0]-3.0) - D*system.configs[0].dq
#        u = tuple([u1,u2,u3,u4])

        k = np.array([0.1 * axis[1], 0.1 * axis[0]])

        # advance simluation one timestep using trep VI
        mvi.step(mvi.t2 + dt, u, k)
        q = mvi.q2
        t = mvi.t2
        configs.data = tuple(q) + u

        jointstates.header.stamp = rospy.Time.now()
        jointstates.name = ["q1ballrx", "q1ballry"]
        jointstates.position = [q[3], q[4]]
        jointstates.velocity = [system.configs[5].dq, system.configs[6].dq]

        # send transform data to rviz
        broadcaster.sendTransform(
            (q[2], q[1], q[0]),
            tf.transformations.quaternion_from_euler(0, 0, 0),
            rospy.Time.now(), "quad1", "world")
        broadcaster.sendTransform(
            (0, 0, 0), tf.transformations.quaternion_from_euler(q[5], q[6], 0),
            rospy.Time.now(), "quadr", "quad1")
        statepub.publish(jointstates)
        pub.publish(configs)
        r.sleep()
Beispiel #15
0
def create_initial_trajectory():

    puppet = puppets.Puppet(joint_forces=False,
                            string_forces=False,
                            string_constraints=True)

    puppet.q = {
        "torso_rx": -0.05,
        #"torso_ry" : 0.1,
        "torso_tz": 0.0,
        "lelbow_rx": 1.57,
        "relbow_rx": 1.57,
        "lhip_rx": pi / 2 - 0.6,
        "rhip_rx": pi / 2 - 0.6,
        "lknee_rx": -pi / 2 + 0.6,
        "rknee_rx": -pi / 2 + 0.6,
    }
    puppet.project_string_controls()

    q0 = puppet.q
    u0 = tuple([0.0] * len(puppet.inputs))
    qk2_0 = puppet.qk
    dt = 0.01
    # Create and initialize a variational integrator for the system.
    gmvi = trep.MidpointVI(puppet)
    gmvi.initialize_from_configs(0.0, q0, dt, q0)

    left_leg_index = puppet.get_config("left_leg_string-length").k_index
    right_leg_index = puppet.get_config("right_leg_string-length").k_index
    left_arm_index = puppet.get_config("left_arm_string-length").k_index
    right_arm_index = puppet.get_config("right_arm_string-length").k_index

    def calc_vk():
        v2 = [(q2 - q1) / (gmvi.t2 - gmvi.t1)
              for (q2, q1) in zip(gmvi.q2, gmvi.q1)]
        v2 = v2[len(puppet.dyn_configs):]
        return v2

    q = [gmvi.q2]
    p = [gmvi.p2]
    v = [calc_vk()]
    t = [gmvi.t2]
    while gmvi.t1 < 10.0:
        # For our kinematic inputs, we first copy our starting position.
        qk2 = list(qk2_0)
        # Now we want to move some of the strings up and down.
        qk2[left_leg_index] += -0.1 * sin(0.6 * pi * gmvi.t1)
        qk2[right_leg_index] += 0.1 * sin(0.6 * pi * gmvi.t1)
        qk2[left_arm_index] += 0.1 * sin(0.6 * pi * gmvi.t1)
        qk2[right_arm_index] += -0.1 * sin(0.6 * pi * gmvi.t1)
        qk2 = tuple(qk2)

        gmvi.step(gmvi.t2 + dt, u0, qk2)
        q.append(gmvi.q2)
        p.append(gmvi.p2)
        v.append(calc_vk())
        t.append(gmvi.t2)
        # The puppet can take a while to simulate, so print out the time
        # occasionally to indicate our progress.
        if abs(gmvi.t2 - round(gmvi.t2)) < dt / 2.0:
            print "t =", gmvi.t2

    dsys = discopt.DSystem(gmvi, t)

    q = np.array(q)
    rho = q[1:, puppet.nQd:]

    X, U = dsys.build_trajectory(q, p, v, None, rho)

    return puppet, dsys, t, X, U
Beispiel #16
0
    def __init__(self, sys):
        rospy.loginfo("Starting puppet simulator node")
        self.legs_bool = rospy.get_param('legs', False)
        self.shoulders_bool = rospy.get_param('shoulders', False)
        # first, let's just define the initial configuration of the system:
        self.sys = sys
        self.q0_guess = {
            # torso position
            'TorsoZ' : BODY_HEIGHT,
            # body robot
            'BodyRobotTheta' : -pi/2,
            'BodyRobotZ' : BODY_HEIGHT + SHOULDER_LENGTH,
            'LeftShoulderString' : SHOULDER_LENGTH,
            'RightShoulderString' : SHOULDER_LENGTH,
            # left robot
            'LeftRobotTheta' : -pi/2,
            'LeftRobotX' : pd.torso_width/2,
            'LeftRobotY' : -(pd.humerus_length + pd.radius_length),
            'LeftRobotZ' : BODY_HEIGHT + ARM_LENGTH,
            'LeftArmString' : ARM_LENGTH,
            # right robot
            'RightRobotTheta' : -pi/2,
            'RightRobotX' : -pd.torso_width/2,
            'RightRobotY' : -(pd.humerus_length + pd.radius_length),
            'RightRobotZ' : BODY_HEIGHT + ARM_LENGTH,
            'RightArmString' : ARM_LENGTH,
            # left arm
            'LShoulderPhi' : -pi/2,
            # right arm
            'RShoulderPhi' : -pi/2,
            # shoulder robots
            'LeftShoulderRobotTheta' : -pi/2,
            'LeftShoulderRobotZ' : BODY_HEIGHT + SHOULDER_LENGTH,
            'LeftShoulderRobotX' : pd.torso_width_1/2,
            'RightShoulderRobotTheta' : -pi/2,
            'RightShoulderRobotZ' : BODY_HEIGHT + SHOULDER_LENGTH,
            'RightShoulderRobotX' : -pd.torso_width_1/2,
            }
        if self.legs_bool:
            self.q0_guess.update( {
                # left leg robot
                'LeftLegRobotTheta' : -pi/2,
                'LeftLegRobotX' : pd.torso_width/4,
                'LeftLegRobotY' : -(pd.humerus_length + pd.radius_length),
                'LeftLegRobotZ' : BODY_HEIGHT + LEG_LENGTH,
                'LeftLegString' : LEG_LENGTH,
                # right leg robot
                'RightLegRobotTheta' : -pi/2,
                'RightLegRobotX' : -pd.torso_width/4,
                'RightLegRobotY' : -(pd.humerus_length + pd.radius_length),
                'RightLegRobotZ' : BODY_HEIGHT + LEG_LENGTH,
                'RightLegString' : LEG_LENGTH,
                })
        self.sys.q = 0
        self.sys.q = self.q0_guess
        self.sys.satisfy_constraints()
        self.sys.minimize_potential_energy(keep_kinematic=True)
        self.q0 = self.sys.q
        self.mvi = trep.MidpointVI(self.sys)
        self.mvi.initialize_from_configs(0, self.sys.q, DT, self.sys.q)

        # fill out a message, and store it in the class so that I can update it
        # whenever necessary
        self.mappings = {
            'left_shoulder_psi' : 'LShoulderPsi',
            'left_shoulder_theta' : 'LShoulderTheta',
            'left_shoulder_phi' : 'LShoulderPhi',
            'right_shoulder_psi' : 'RShoulderPsi',
            'right_shoulder_theta' : 'RShoulderTheta',
            'right_shoulder_phi' : 'RShoulderPhi',
            'left_elbow_phi' : 'LElbowPhi',
            'right_elbow_phi' : 'RElbowPhi',
            'left_hip_psi' : 'LHipPsi',
            'left_hip_theta' : 'LHipTheta',
            'left_hip_phi' : 'LHipPhi',
            'right_hip_psi' : 'RHipPsi',
            'right_hip_theta' : 'RHipTheta',
            'right_hip_phi' : 'RHipPhi',
            'left_knee_phi' : 'LKneePhi',
            'right_knee_phi' : 'RKneePhi',
            }
        self.js = JS()
        self.names = [x for x in self.mappings.keys()]
        self.js.name = self.names
        self.js.header.frame_id = 'world'
        self.update_values()
        self.count_exceptions = 0

        # define tf broadcaster and listener
        self.br = tf.TransformBroadcaster()
        self.listener = tf.TransformListener()

        # add constraint visualization:
        self.con_vis = []
        # hands:
        for i in 4,5:
            self.con_vis.append(StringMarker(fm[i].input_frame,
                                             fm[i].puppet_frames,
                                             self.listener))
        if self.shoulders_bool: # shoulders
            for i in 2,3:
                self.con_vis.append(StringMarker(fm[i].input_frame,
                                                 fm[i].puppet_frames,
                                                 self.listener))
        else: # body
            for i in 0,1:
                self.con_vis.append(StringMarker(fm[1].input_frame,
                                                 fm[1].puppet_frames[i],
                                                 self.listener))
        if self.legs_bool: # legs
            for i in 6,7:
                self.con_vis.append(StringMarker(fm[i].input_frame,
                                                 fm[i].puppet_frames,
                                                 self.listener))
        # define a publisher for the joint states
        self.joint_pub = rospy.Publisher("joint_states", JS)
        # define a publisher for the constraint Markers
        self.con_pub = rospy.Publisher("visualization_markers", VM.MarkerArray)
        # define a timer for publishing the frames and tf's
        rospy.Timer(rospy.Duration(1.0/tf_freq), self.send_joint_states)
        # request that we get a service handler:
        rospy.loginfo("Waiting for reset handling service...")
        rospy.wait_for_service("interface_reset")
        self.reset_srv_client = rospy.ServiceProxy("interface_reset", SS.Empty)
        # offer service to reset simulation
        self.reset_srv_provider = rospy.Service("simulator_reset", SS.Empty,
                                                self.reset_provider)
        # define a timer for integrating the state of the VI
        rospy.loginfo("Starting integration...")
        rospy.Timer(rospy.Duration(DT), self.integrate_vi)
Beispiel #17
0

if __name__ == '__main__':
    puppet = Puppet(joint_forces=False,
                    string_forces=False,
                    string_constraints=True)
    puppet.get_config('torso_rx').q = 0.1
    puppet.get_config('torso_ry').q = 0.1
    puppet.project_string_controls()

    q0 = puppet.get_q()
    u0 = tuple([0.0] * len(puppet.inputs))
    qk2 = puppet.get_qk()
    dt = 0.01
    # Create and initialize a variational integrator for the system.
    gmvi = trep.MidpointVI(puppet)
    gmvi.initialize_from_configs(0.0, q0, dt, q0)

    q = [gmvi.q2]
    t = [gmvi.t2]
    while gmvi.t1 < 10.0:
        gmvi.step(gmvi.t2 + dt, u0, qk2)
        q.append(gmvi.q2)
        t.append(gmvi.t2)
        # The puppet can take a while to simulate, so print out the time
        # occasionally to indicate our progress.
        if abs(gmvi.t2 - round(gmvi.t2)) < dt / 2.0:
            print "t =", gmvi.t2

    visualize_3d([PuppetVisual(puppet, t, q)])
Beispiel #18
0
tf = 10.0
dt = 0.01

# Define a simple 2 link pendulum with a force input on the middle joint
system = trep.System()
frames = [
    tz(-1),  # Provided as an angle reference
    ry("theta1"),
    [tz(-2, mass=1), [ry("theta2"), [tz(-2, mass=1)]]]
]
system.import_frames(frames)
trep.potentials.Gravity(system, (0, 0, -9.8))
trep.forces.Damping(system, 1.2)
trep.forces.ConfigForce(system, 'theta2', 'theta2-torque')
mvi = trep.MidpointVI(system)  # Create the variational integrator


# Define a function to run the simulation and return the result
def simulate(mvi, u_func, dt, tf):
    q = [mvi.q2]
    p = [mvi.p2]
    t = [mvi.t2]
    while mvi.t1 < tf:
        mvi.step(mvi.t2 + dt, u_func(mvi.t1))
        q.append(mvi.q2)
        p.append(mvi.p2)
        t.append(mvi.t2)
    return t, q, p

Beispiel #19
0
amp  = np.radians(10)   # amplitude in radians
freq = 8                # frequency in Hz.
def h_func(t):
    return amp*np.sin(2*np.pi*freq*t)

def hdt_func(t):
    return 2*np.pi*freq*amp*np.cos(2*np.pi*freq*t)

base_motion = {'h': h_func, 'hdt': hdt_func}

# Create the whisker and the integrator.
fx = []
for a in [0, 10, 20, 30]:
    parameters['a'] = a
    whisker = ws.whisker.Whisker2D(parameters, base_motion)
    mvi = trep.MidpointVI(whisker)

    # Simulate and visualize the whisking.
    tf = 2.0
    dt = 0.005
    (t, q, lam) = ws.collisions.sim.simulate(mvi, tf, dt)

    base_forces = ws.simulation.simulate.get_base_forces_2d(whisker, lam, dt)
    fx.append(base_forces['Fy']*1e6)

# Plot the results for each curvature.
N = 200
plt.rc('text', usetex=True)
matplotlib.rcParams.update({'font.size':18})
fig = plt.figure(facecolor='white',figsize=(12,5))
ax = plt.axes()
Beispiel #20
0
# There is no guarantee that the configuration we just set is
# consistent with the system's constraints.  We can call
# System.satisfy_constraints() to have trep find a configuration that
# is consistent.  This just uses a root-finding method to solve h(q) =
# 0 starting from the current configuration.  There is no guarantee
# that it will always converge and no guarantee the final
# configuration is close to the original one.
system.satisfy_constraints()

# Now we'll extract the current configuration into a tuple to use as
# initial conditions for a variational integrator.
q0 = system.q

# Create and initialize the variational integrator
mvi = trep.MidpointVI(system)
mvi.initialize_from_configs(0.0, q0, dt, q0)

# This is our simulation loop.  We save the results in two lists.
q = [mvi.q2]
t = [mvi.t2]
while mvi.t1 < tf:
    mvi.step(mvi.t2 + dt)
    q.append(mvi.q2)
    t.append(mvi.t2)

# After the simulation is finished, we can visualize the results.  The
# viewer can automatically draw a primitive representation for
# arbitrary systems from the tree structure.  print_instructions() has
# the viewer print out basic usage information to the console.
visual.visualize_3d([visual.VisualItem3D(system, t, q)])
Beispiel #21
0
def QuadMain(isjoy):
    def make_state_cost(dsys, base, x):
        weight = base * np.ones((dsys.nX, ))
        weight[system.get_config('ballx').index] = 50
        weight[system.get_config('bally').index] = 50
        weight[system.get_config('ballz').index] = 25
        weight[system.get_config('quad1bry').index] = 500
        weight[system.get_config('quad1brx').index] = 100
        weight[system.get_config('quad1ry').index] = 10
        weight[system.get_config('quad1rx').index] = 10
        weight[system.get_config('quad1rz').index] = 1
        weight[system.get_config('quad2bry').index] = 500
        weight[system.get_config('quad2brx').index] = 15
        weight[system.get_config('quad2ry').index] = 10
        weight[system.get_config('quad2rx').index] = 10
        weight[system.get_config('quad2rz').index] = 1
        return np.diag(weight)

    def make_input_cost(dsys, base, x):
        weight = base * np.ones((dsys.nU, ))
        # weight[system.get_input('x-force').index] = x
        return np.diag(weight)

    quad1cm_m = 1.0
    quadmotor1_m = 1.0
    quad2cm_m = 1.0
    quadmotor2_m = 1.0
    ball_m = 0.5

    dt = 0.01  # timestep set to 10ms

    # Create a new trep system - 6 generalized coordinates for quadrotor: x,y,z,roll,pitch,yaw
    system = trep.System()
    trep.potentials.Gravity(system, name="Gravity")

    # define ball frame
    ballz = trep.Frame(system.world_frame, trep.TZ, "ballz")
    bally = trep.Frame(ballz, trep.TY, "bally")
    ballx = trep.Frame(bally, trep.TX, "ballx")
    ballx.set_mass(ball_m)

    # define quadrotor 1 frame
    quad1bry = trep.Frame(ballx, trep.RY, "quad1bry")
    quad1brx = trep.Frame(quad1bry, trep.RX, "quad1brx")
    quad1cm = trep.Frame(quad1brx, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 2)),
                         "quad1cm")
    quad1ry = trep.Frame(quad1cm, trep.RY, "quad1ry")
    quad1rx = trep.Frame(quad1ry, trep.RX, "quad1rx")
    quad1rz = trep.Frame(quad1rx, trep.RZ, "quad1rz")

    quad1cm.set_mass(quad1cm_m)  # central point mass

    # define quadrotor 1 motor positions and mass
    quad1m1 = trep.Frame(quad1rz, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 0, 0)),
                         "quad1m1")
    quad1m1.set_mass(quadmotor1_m)
    quad1m2 = trep.Frame(quad1rz, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (-1, 0, 0)),
                         "quad1m2")
    quad1m2.set_mass(quadmotor1_m)
    quad1m3 = trep.Frame(quad1rz, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 1, 0)),
                         "quad1m3")
    quad1m3.set_mass(quadmotor1_m)
    quad1m4 = trep.Frame(quad1rz, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (0, -1, 0)),
                         "quad1m4")
    quad1m4.set_mass(quadmotor1_m)

    # set four thrust vectors with inputs u1,u2,u3,u4
    trep.forces.BodyWrench(system,
                           quad1m1, (0, 0, 'u1q1', 0, 0, 0),
                           name='quad1w1')
    trep.forces.BodyWrench(system,
                           quad1m2, (0, 0, 'u2q1', 0, 0, 0),
                           name='quad1w2')
    trep.forces.BodyWrench(system,
                           quad1m3, (0, 0, 'u3q1', 0, 0, 0),
                           name='quad1w3')
    trep.forces.BodyWrench(system,
                           quad1m4, (0, 0, 'u4q1', 0, 0, 0),
                           name='quad1w4')

    # define quadrotor 2 frame
    quad2bry = trep.Frame(ballx, trep.RY, "quad2bry")
    quad2brx = trep.Frame(quad2bry, trep.RX, "quad2brx")
    quad2cm = trep.Frame(quad2brx, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 2)),
                         "quad2cm")
    quad2ry = trep.Frame(quad2cm, trep.RY, "quad2ry")
    quad2rx = trep.Frame(quad2ry, trep.RX, "quad2rx")
    quad2rz = trep.Frame(quad2rx, trep.RZ, "quad2rz")

    quad2cm.set_mass(quad2cm_m)  # central point mass

    # define quadrotor 2 motor positions and mass
    quad2m1 = trep.Frame(quad2rz, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 0, 0)),
                         "quad2m1")
    quad2m1.set_mass(quadmotor2_m)
    quad2m2 = trep.Frame(quad2rz, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (-1, 0, 0)),
                         "quad2m2")
    quad2m2.set_mass(quadmotor2_m)
    quad2m3 = trep.Frame(quad2rz, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 1, 0)),
                         "quad2m3")
    quad2m3.set_mass(quadmotor2_m)
    quad2m4 = trep.Frame(quad2rz, trep.CONST_SE3,
                         ((1, 0, 0), (0, 1, 0), (0, 0, 1), (0, -1, 0)),
                         "quad2m4")
    quad2m4.set_mass(quadmotor2_m)

    # set four thrust vectors with inputs u1,u2,u3,u4
    trep.forces.BodyWrench(system,
                           quad2m1, (0, 0, 'u1q2', 0, 0, 0),
                           name='quad2w1')
    trep.forces.BodyWrench(system,
                           quad2m2, (0, 0, 'u2q2', 0, 0, 0),
                           name='quad2w2')
    trep.forces.BodyWrench(system,
                           quad2m3, (0, 0, 'u3q2', 0, 0, 0),
                           name='quad2w3')
    trep.forces.BodyWrench(system,
                           quad2m4, (0, 0, 'u4q2', 0, 0, 0),
                           name='quad2w4')

    # set quadrotor initial altitude at 5m
    system.get_config("ballz").q = 0.0

    system.get_config("quad1bry").q = (math.pi / 2 - math.acos(1.5 / 2.0))
    system.get_config("quad2bry").q = -(math.pi / 2 - math.acos(1.5 / 2.0))

    horzf = 0.5 * ball_m * 9.8 * math.tan((math.pi / 2 - math.acos(1.5 / 2.0)))
    vertf = (0.5 * ball_m + quad1cm_m + 4 * quadmotor1_m) * 9.8
    quad1ang = math.atan(horzf / ((quad1cm_m + 4 * quadmotor1_m) * 9.8))

    system.get_config(
        "quad1ry").q = -(math.pi / 2 - math.acos(1.5 / 2.0)) + quad1ang
    system.get_config("quad2ry").q = (math.pi / 2 -
                                      math.acos(1.5 / 2.0)) - quad1ang

    # Now we'll extract the current configuration into a tuple to use as
    # initial conditions for a variational integrator.
    q0 = system.q

    # Create the discrete system
    mvi = trep.MidpointVI(system)
    t = np.arange(0.0, 10.0, 0.01)
    dsys = discopt.DSystem(mvi, t)

    # Generate cost function
    Qcost = make_state_cost(dsys, 1, 0.00)
    Rcost = make_input_cost(dsys, 0.01, 0.01)

    totuf = math.sqrt(math.pow(horzf, 2) + math.pow(vertf, 2))
    u0 = np.array([
        totuf / 4, totuf / 4, totuf / 4, totuf / 4, totuf / 4, totuf / 4,
        totuf / 4, totuf / 4
    ])
    u = tuple(u0)

    mvi.initialize_from_configs(0.0, q0, dt, q0)
    pref = mvi.p2

    Uint = np.zeros((len(t) - 1, system.nu))
    qd = np.zeros((len(t), system.nQ))
    pd = np.zeros((len(t), system.nQ))
    for i, t in enumerate(t[:-1]):
        Uint[i, :] = u0
        qd[i, :] = q0
        pd[i, :] = pref
    qd[len(qd) - 1, :] = q0
    pd[len(pd) - 1, :] = pref

    Qk = lambda k: Qcost
    (X, U) = dsys.build_trajectory(Q=qd, p=pd, u=Uint)
    Kstab = dsys.calc_feedback_controller(X, U, Qk)

    #print Kstab[0]

    # Create and initialize the variational integrator)
    u = tuple(u0)
    #mvi.initialize_from_configs(0.0, q0, dt, q0)

    # These are our simulation variables.
    q = mvi.q2
    p = mvi.p2
    pref = p
    t = mvi.t2

    # start ROS node to broadcast transforms to rviz
    rospy.init_node('quad_simulator')
    broadcaster = tf.TransformBroadcaster()
    pub = rospy.Publisher('config', Float32MultiArray, queue_size=2)
    statepub = rospy.Publisher('joint_states', JointState, queue_size=2)

    jointstates = JointState()
    configs = Float32MultiArray()
    if isjoy == True:
        markerpub = rospy.Publisher('refmark', Marker, queue_size=2)
        refmark = Marker()

    if isjoy == False:
        ############### NEW ################################33
        # create an interactive marker server on the topic namespace simple_marker
        server = InteractiveMarkerServer("simple_marker")

        # create an interactive marker for our server
        int_marker = InteractiveMarker()
        int_marker.header.frame_id = "/world"
        int_marker.name = "my_marker"
        int_marker.description = "Simple 1-DOF Control"
        int_marker.pose.position.z = 2.0

        # create a grey box marker
        box_marker = Marker()
        box_marker.type = Marker.SPHERE
        box_marker.scale.x = 0.15
        box_marker.scale.y = 0.15
        box_marker.scale.z = 0.15
        box_marker.color.r = 0.0
        box_marker.color.g = 1.0
        box_marker.color.b = 0.0
        box_marker.color.a = 1.0

        # create a non-interactive control which contains the box
        box_control = InteractiveMarkerControl()
        box_control.orientation.w = 1
        box_control.orientation.x = 0
        box_control.orientation.y = 1
        box_control.orientation.z = 0
        box_control.name = "rotate_x"
        box_control.name = "move_x"
        box_control.always_visible = True
        box_control.interaction_mode = InteractiveMarkerControl.MOVE_PLANE
        int_marker.controls.append(box_control)

        box_control = InteractiveMarkerControl()
        box_control.orientation.w = 1
        box_control.orientation.x = 0
        box_control.orientation.y = 1
        box_control.orientation.z = 0
        box_control.name = "rotate_x"
        box_control.name = "move_x"
        box_control.always_visible = True
        box_control.interaction_mode = InteractiveMarkerControl.MOVE_PLANE
        box_control.markers.append(box_marker)
        int_marker.controls.append(box_control)

        # add the interactive marker to our collection &
        # tell the server to call processFeedback() when feedback arrives for it
        server.insert(int_marker, processFeedback)

        # 'commit' changes and send to all clients
        server.applyChanges()
############### END NEW ###############################
    if isjoy == True:
        # subscribe to joystick topic from joy_node
        rospy.Subscriber("joy", Joy, joycall)

    r = rospy.Rate(100)  # simulation rate set to 100Hz

    # Simulator Loop
    while not rospy.is_shutdown():

        # reset simulator if trigger pressed
        if buttons[0] == 1:
            mvi.initialize_from_configs(0.0, q0, dt, q0)

        qref = [0, axis[1], axis[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        u = tuple(u0 - np.dot(Kstab[0], np.append(q - q0 - qref, p - pref)))

        # advance simluation one timestep using trep VI

        try:
            mvi.step(mvi.t2 + dt, u)
        except trep.ConvergenceError:
            print 'Trep simulation error - system resetting...'
            rospy.sleep(2.)
            mvi.initialize_from_configs(0.0, q0, dt, q0)

        q = mvi.q2
        p = mvi.p2
        t = mvi.t2
        configs.data = tuple(q) + u

        if isjoy == True:
            refmark.header.frame_id = "/world"
            refmark.header.stamp = rospy.Time.now()
            refmark.type = 2
            refmark.scale.x = 0.15
            refmark.scale.y = 0.15
            refmark.scale.z = 0.15
            refmark.color.r = 0.0
            refmark.color.g = 1.0
            refmark.color.b = 0.0
            refmark.color.a = 1.0
            refmark.pose.position.y = axis[1]
            refmark.pose.position.x = axis[0]
            refmark.pose.position.z = 2.0

        jointstates.header.stamp = rospy.Time.now()
        jointstates.name = [
            "quad1bry", "quad1brx", "quad1ry", "quad1rx", "quad1rz",
            "quad2bry", "quad2brx", "quad2ry", "quad2rx", "quad2rz"
        ]
        jointstates.position = [
            q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12]
        ]
        jointstates.velocity = [
            system.configs[3].dq, system.configs[4].dq, system.configs[5].dq,
            system.configs[6].dq, system.configs[7].dq, system.configs[8].dq,
            system.configs[9].dq, system.configs[10].dq, system.configs[11].dq,
            system.configs[12].dq
        ]

        # send transform data to rviz
        broadcaster.sendTransform(
            (q[2], q[1], q[0] + 2),
            tf.transformations.quaternion_from_euler(0.0, 0.0, 0.0),
            rospy.Time.now(), "ball", "world")
        statepub.publish(jointstates)
        pub.publish(configs)
        if isjoy == True:
            markerpub.publish(refmark)
        r.sleep()