Ejemplo n.º 1
0
    def add_level(frame, link=0, kinematic=False):
        """
		Recursively add links to a system by attaching a new link to
		the specified frame.
		"""
        if link == num_links:
            return

        # Create a rotation for the pendulum.
        # The first argument is the name of the frame, the second is
        # the transformation type, and the third is the name of the
        # configuration variable that parameterizes the
        # transformation.
        child = trep.Frame(frame,
                           trep.RX,
                           "link-%d" % link,
                           "link-%d" % link,
                           kinematic=kinematic)

        # Move down to create the length of the pendulum link.
        child = trep.Frame(child, trep.TZ, -1)
        # Add mass to the end of the link (only a point mass, no
        # rotational intertia
        child.set_mass(1.0)

        add_level(child, link + 1)
    def add_level(frame, link=0):
        """
        Recusively add links to a system by attaching a new link to
        the specified frame.
        """
        if link == num_links:
            return

        # Create a rotation for the pendulum.
        # The first argument is the name of the frame, the second is
        # the transformation type, and the third is the name of the
        # configuration variable that parameterizes the
        # transformation.
        config_name = 'theta-%d' % link
        child = trep.Frame(frame, trep.RY, config_name, "link-%d" % link)

        if not hybrid_wrenched:
            trep.forces.ConfigForce(child.system,
                                    config_name,
                                    'torque-%d' % link,
                                    name='joint-force-%d' % link)

        # Move down to create the length of the pendulum link.
        child = trep.Frame(child, trep.TZ, -1)
        # Add mass to the end of the link (only a point mass, no
        # rotational inertia)
        child.set_mass(1.0)

        if hybrid_wrenched:
            trep.forces.HybridWrench(child.system,
                                     child, ('wrench-x-%d' % link, 0.0, 0.0),
                                     name='wrench-%d' % link)

        add_level(child, link + 1)
Ejemplo n.º 3
0
 def build_leg(self, attach, n, L, l):
     # upper leg:
     child = trep.Frame(attach, trep.RX, "leg_%d_th1" % n, "leg_%d_th1" % n)
     child = trep.Frame(child,
                        trep.TY,
                        -L / 2.,
                        "leg_%d_upper_inertial" % n,
                        mass=.10)
     child = trep.Frame(child, trep.TY, -L / 2., "leg_%d_upper_end" % n)
     # first universal joint:
     child = trep.Frame(child, trep.RX, "leg_%d_th2" % n, "leg_%d_th2" % n)
     child = trep.Frame(child, trep.RZ, "leg_%d_th3" % n, "leg_%d_th3" % n)
     # lower leg:
     child = trep.Frame(child,
                        trep.TY,
                        -l / 2,
                        "leg_%d_lower_inertial" % n,
                        mass=.07)
     child = trep.Frame(child, trep.TY, -l / 2., "leg_%d_lower_end" % n)
     # second universal joint:
     child = trep.Frame(child, trep.RZ, "leg_%d_th4" % n, "leg_%d_th4" % n)
     child = trep.Frame(child, trep.RX, "leg_%d_th5" % n, "leg_%d_end" % n)
     return
Ejemplo n.º 4
0
    def import_frames(self, children):
        """
        Import a tree of frames from a tree description.
        """
        self.system.hold_structure_changes()
        while children:
            info = children[0]
            children = children[1:]
            if not isinstance(info, trep.frame.FrameDef):
                raise TypeError('Frame definition expected instead of: %r', info)

            frame = trep.Frame(self, info.transform_type, info.param,
                               name=info.name,
                               kinematic=info.kinematic,
                               mass=info.mass)

            if children and isinstance(children[0], list):
                frame.import_frames(children[0])
                children = children[1:]
        self.system.resume_structure_changes()
Ejemplo n.º 5
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()
Ejemplo n.º 6
0
 def __init__(self, L_base, L_platform, R_base, R_platform):
     # first let's create an empty system, and build the base platform:
     super(DeltaRobotTrep, self).__init__()
     # triangle sizes:
     s_base = R_base * 6. / np.sqrt(3)
     s_platform = R_platform * 6. / np.sqrt(3)
     # center of circles to platform vertices:
     u_base = s_base * np.sqrt(3) / 3.
     u_platform = s_platform * np.sqrt(3) / 3.
     # center of circles to triangle edges
     w_base = R_base
     w_platform = R_platform
     # LEG 1 ATTACHMENT
     _ = trep.Frame(self.world_frame, trep.TY, -w_base, "base_attach_leg1")
     # LEG 2 ATTACHMENT
     child = trep.Frame(self.world_frame, trep.TX,
                        w_base * np.cos(30 * pi / 180.))
     child = trep.Frame(child, trep.TY, w_base * np.sin(30 * pi / 180.))
     _ = trep.Frame(child, trep.RZ, 120 * pi / 180., "base_attach_leg2")
     # LEG 3 ATTACHMENT
     child = trep.Frame(self.world_frame, trep.TX,
                        -w_base * np.cos(30 * pi / 180.))
     child = trep.Frame(child, trep.TY, w_base * np.sin(30 * pi / 180.))
     _ = trep.Frame(child, trep.RZ, 240 * pi / 180., "base_attach_leg3")
     # BUILD LEGS
     self.build_leg(self.get_frame("base_attach_leg1"), 1, L_base,
                    L_platform)
     self.build_leg(self.get_frame("base_attach_leg2"), 2, L_base,
                    L_platform)
     self.build_leg(self.get_frame("base_attach_leg3"), 3, L_base,
                    L_platform)
     # ADD PLATFORM AND ATTACHMENTS:
     child = trep.Frame(self.world_frame, trep.TX, "platform_x",
                        "platform_x")
     child = trep.Frame(child, trep.TY, "platform_y", "platform_y")
     self.platform_center = trep.Frame(child,
                                       trep.TZ,
                                       "platform_z",
                                       "platform_z",
                                       mass=.15)
     _ = trep.Frame(self.platform_center, trep.TY, -u_platform,
                    "platform_attach_leg1")
     child = trep.Frame(self.platform_center, trep.TX,
                        u_platform * np.cos(30 * pi / 180.))
     child = trep.Frame(child, trep.TY, u_platform * np.sin(30 * pi / 180.))
     _ = trep.Frame(child, trep.RZ, 120 * pi / 180., "platform_attach_leg2")
     child = trep.Frame(self.platform_center, trep.TX,
                        -u_platform * np.cos(30 * pi / 180.))
     child = trep.Frame(child, trep.TY, u_platform * np.sin(30 * pi / 180.))
     _ = trep.Frame(child, trep.RZ, 240 * pi / 180., "platform_attach_leg3")
     # NOW ADD CONSTRAINTS
     trep.constraints.PointToPoint3D(self, "platform_attach_leg1",
                                     "leg_1_end")
     trep.constraints.PointToPoint3D(self, "platform_attach_leg2",
                                     "leg_2_end")
     trep.constraints.PointToPoint3D(self, "platform_attach_leg3",
                                     "leg_3_end")
     # ADD SPRINGS
     q_neutral = 22.5 * pi / 180.
     stiffness = 10
     trep.potentials.ConfigSpring(self,
                                  'leg_1_th1',
                                  k=stiffness,
                                  q0=q_neutral)
     trep.potentials.ConfigSpring(self,
                                  'leg_2_th1',
                                  k=stiffness,
                                  q0=q_neutral)
     trep.potentials.ConfigSpring(self,
                                  'leg_3_th1',
                                  k=stiffness,
                                  q0=q_neutral)
     # ADD GRAVITY AND DAMPING
     trep.potentials.Gravity(self, gravity=[0, 0, -9.8], name="gravity")
     trep.forces.Damping(self, 0.05)
     return
Ejemplo n.º 7
0
def add_child_frame(parent_name, parent_frame, links, joints, prefix):
    for joint in joints:
        if joint.find('parent').get('link') == parent_name:
            child_name = joint.find('child').get('link')
            joint_name = joint.get('name')

            # check if joint should be kinematically controlled
            if joint.get('kinematic') == 'True':
                iskin = True
            else:
                iskin = False
            
            # First create new joint frame if origin tag is specified
            j_origin = joint.find('origin')
            if j_origin == None:
                joint_frame = parent_frame
            else:
                if j_origin.get('xyz') is not None:
                    j_xyz = str.split(j_origin.get('xyz'))
                else:
                    j_xyz = [0.0, 0.0, 0.0]
                if j_origin.get('rpy') is not None:
                    j_rpy = str.split(j_origin.get('rpy'))
                else:
                    j_rpy = [0.0, 0.0, 0.0]
                origin = transform([float(j_xyz[0]),float(j_xyz[1]),float(j_xyz[2])],[float(j_rpy[0]),float(j_rpy[1]),float(j_rpy[2])])
                joint_frame = trep.Frame(parent_frame, trep.CONST_SE3, origin, name = prefix + joint_name)
            
            # Fixed Joint
            if joint.get('type') == 'fixed':
                child_frame = joint_frame
                child_frame.name = prefix + child_name
            
            # Continuous Joint
            elif joint.get('type') == 'continuous':
                j_axis = joint.find('axis')
                if j_axis == None:
                    j_xyz = [1, 0, 0]
                else:
                    j_xyz = str.split(j_axis.get('xyz'))
                    j_xyz = [float(j_xyz[0]), float(j_xyz[1]), float(j_xyz[2])]
                    j_xyz /= norm(j_xyz)
                    
                if np.dot(j_xyz, [1,0,0]) > 0.99:
                    #rotate about x-axis
                    child_frame = trep.Frame(joint_frame, trep.RX, prefix + joint_name, name = prefix + child_name, kinematic = iskin) 
                    
                elif np.dot(j_xyz, [0,1,0]) > 0.99:
                    #rotate about y-axis
                    child_frame = trep.Frame(joint_frame, trep.RY, prefix + joint_name, name = prefix + child_name, kinematic = iskin) 
                    
                elif np.dot(j_xyz, [0,0,1]) > 0.99:
                    #rotate about z-axis
                    child_frame = trep.Frame(joint_frame, trep.RZ, prefix + joint_name, name = prefix + child_name, kinematic = iskin) 
                    
                else:
                    #arbitray axis rotation
                    rotation_mat = rotate(j_xyz)
                    rotation_frame = trep.Frame(joint_frame, trep.CONST_SE3, np.vstack((rotation_mat,[0,0,0])), name = prefix + child_name + '-axis')
                    config_frame = trep.Frame(rotation_frame, trep.RX, prefix + joint_name, name = prefix + joint_name + '-axis', kinematic = iskin)
                    child_frame = trep.Frame(config_frame, trep.CONST_SE3, np.vstack((np.transpose(rotation_mat),[0,0,0])), name = prefix + child_name)
             
            # Prismatic Joint
            elif joint.get('type') == 'prismatic':                  
                j_axis = joint.find('axis')
                if j_axis == None:
                    j_xyz = [1, 0, 0]
                else:
                    j_xyz = str.split(j_axis.get('xyz'))
                    j_xyz = [float(j_xyz[0]), float(j_xyz[1]), float(j_xyz[2])]
                    j_xyz /= norm(j_xyz)
                    
                if np.dot(j_xyz, [1,0,0]) > 0.99:
                    #translate on x-axis
                    child_frame = trep.Frame(joint_frame, trep.TX, prefix + joint_name, name = prefix + child_name, kinematic = iskin) 
                    
                elif np.dot(j_xyz, [0,1,0]) > 0.99:
                    #translate on y-axis
                    child_frame = trep.Frame(joint_frame, trep.TY, prefix + joint_name, name = prefix + child_name, kinematic = iskin) 
                    
                elif np.dot(j_xyz, [0,0,1]) > 0.99:
                    #translate on z-axis
                    child_frame = trep.Frame(joint_frame, trep.TZ, prefix + joint_name, name = prefix + child_name, kinematic = iskin) 
                    
                else:
                    #arbitray axis translation
                    rotation_mat = rotate(j_xyz)
                    translation_frame = trep.Frame(joint_frame, trep.CONST_SE3, np.vstack((rotation_mat,[0,0,0])), name = prefix + child_name + '-axis')
                    config_frame = trep.Frame(translation_frame, trep.TX, prefix + joint_name, name = prefix + joint_name + '-axis', kinematic = iskin)
                    child_frame = trep.Frame(config_frame, trep.CONST_SE3, np.vstack((np.transpose(rotation_mat),[0,0,0])), name = prefix + child_name)
                    
            # Floating Joint - may not enable since robot_state_pubisher doesn't support
            # elif joint.get('type') == 'floating':
                # tx_frame = trep.Frame(joint_frame, trep.TX, joint_name + '-TX') 
                # ty_frame = trep.Frame(tx_frame, trep.TY, joint_name + '-TY') 
                # tz_frame = trep.Frame(ty_frame, trep.TZ, joint_name + '-TZ') 
                # rx_frame = trep.Frame(tz_frame, trep.RX, joint_name + '-RX') 
                # ry_frame = trep.Frame(rx_frame, trep.RY, joint_name + '-RY')
                # child_frame = trep.Frame(ry_frame, trep.RZ, child_name)     
            
            # No match for joint type
            else:
                print "Invalid joint type specified. Exiting..."
                break
            
            # add mass to child link
            inertia_offset = links[child_name]['origin']['xyz']
            inertia_rotate = links[child_name]['origin']['rpy']
            if norm(inertia_offset) + norm(inertia_rotate) > 0.001:
                # need to create link inertial frame
                inertial_frame = trep.Frame(child_frame, trep.CONST_SE3, transform(inertia_offset, inertia_rotate), name = prefix + child_name + '-inertia')
                inertial_frame.set_mass(links[child_name]['mass']['value'], Ixx = links[child_name]['inertia']['ixx'], Iyy = links[child_name]['inertia']['iyy'], Izz = links[child_name]['inertia']['izz'])
            else:
                child_frame.set_mass(links[child_name]['mass']['value'], Ixx = links[child_name]['inertia']['ixx'], Iyy = links[child_name]['inertia']['iyy'], Izz = links[child_name]['inertia']['izz'])
            
            # Start child node recursion
            add_child_frame(child_name, child_frame, links, joints, prefix)
Ejemplo n.º 8
0
def load_urdf(root, system=None, prefix=None):
    if system is None:
        system = trep.System()
    
    if prefix is None:
        prefix = ''

    links = root.findall('link')
    joints = root.findall('joint')

    link_dict = {}
    for link in links:
        inertial = link.find('inertial')
        if inertial is not None:
            inertia = inertial.find('inertia')
            if inertia is not None:
                inertia_dict = inertia.attrib
                for attr in ['ixx','iyy','izz']:
                    if attr in inertia_dict:
                        inertia_dict[attr] = float(inertia_dict[attr])
                    else:
                        inertia_dict[attr] = 0.0
            else:
                inertia_dict = {'ixx':0.0, 'iyy':0.0, 'izz':0.0} 
            origin = inertial.find('origin')
            if origin is not None:
                origin_dict = origin.attrib
                for attr in ['xyz', 'rpy']:
                    if attr in origin_dict:
                        values = str.split(origin_dict[attr])
                        origin_dict[attr] = [float(values[0]),float(values[1]),float(values[2])]
                    else:
                        origin_dict[attr] = [0.0, 0.0, 0.0]                    
            else:
                origin_dict = {'xyz':[0.0, 0.0, 0.0], 'rpy':[0.0, 0.0, 0.0]}   
            mass = inertial.find('mass')
            if mass is not None:
                mass_dict = mass.attrib
                if 'value' in mass_dict:
                    mass_dict['value'] = float(mass_dict['value'])
                else:
                    mass_dict['value'] = 0.0
            else:
                mass_dict = {'value':0.0}
            inertial_dict = {'origin':origin_dict, 'mass':mass_dict, 'inertia':inertia_dict}
        else:
            inertial_dict = {'origin':{'xyz':[0.0, 0.0, 0.0], 'rpy':[0.0, 0.0, 0.0]}, 'mass':{'value':0.0}, 'inertia':{'ixx':0.0, 'iyy':0.0, 'izz':0.0}}
            
        link_dict[link.get('name')] = inertial_dict

    root_link = []
    for link in links:
        name = link.get('name')

        ischild = False
        for joint in joints:
            if joint.find('child').get('link') == name:
                ischild = True
                break
        if not ischild:
            root_link.append(name)

    frames = []
    root_name = root_link[0]

    # check if root is world and add all frames
    if root_name == 'world':
        add_child_frame(root_name, system.world_frame, link_dict, joints, prefix)

    # else, must first create floating link to world_frame then add frames
    else:
        robot_name = root.get('name')
        world_tx = trep.Frame(system.world_frame, trep.TX, prefix + robot_name +'-TX', name = prefix + robot_name +'-TX')
        world_ty = trep.Frame(world_tx, trep.TY, prefix + robot_name +'-TY', name = prefix + robot_name +'-TY') 
        world_tz = trep.Frame(world_ty, trep.TZ, prefix + robot_name +'-TZ', name = prefix + robot_name +'-TZ') 
        world_rx = trep.Frame(world_tz, trep.RX, prefix + robot_name +'-RX', name = prefix + robot_name +'-RX')  
        world_ry = trep.Frame(world_rx, trep.RY, prefix + robot_name +'-RY', name = prefix + robot_name +'-RY')  
        root_frame = trep.Frame(world_ry, trep.RZ, prefix + robot_name +'-RZ', name = prefix + root_name)  

        # add mass to root frame
        inertia_offset = link_dict[root_name]['origin']['xyz']
        inertia_rotate = link_dict[root_name]['origin']['rpy']
        if norm(inertia_offset) + norm(inertia_rotate) > 0.001:
            # need to create link inertial frame
            inertial_frame = trep.Frame(root_frame, trep.CONST_SE3, transform(inertia_offset, inertia_rotate), name = prefix + root_name + '-inertia')
            inertial_frame.set_mass(link_dict[root_name]['mass']['value'], Ixx = link_dict[root_name]['inertia']['ixx'], Iyy = link_dict[root_name]['inertia']['iyy'], Izz = link_dict[root_name]['inertia']['izz'])
        else:
            root_frame.set_mass(link_dict[root_name]['mass']['value'], Ixx = link_dict[root_name]['inertia']['ixx'], Iyy = link_dict[root_name]['inertia']['iyy'], Izz = link_dict[root_name]['inertia']['izz'])      

        add_child_frame(root_name, root_frame, link_dict, joints, prefix)


    # add damping to joint if specified
    try:
        damping = system.get_force('system-damping') #find damping if previously created
    except KeyError:
        damping = trep.forces.Damping(system, 0.0, name='system-damping') #create damping class if not

    for joint in joints:
        jdyn=joint.find('dynamics')
        if jdyn is not None:
            jdamp=jdyn.get('damping')
            if jdamp is not None and system.get_config(prefix + joint.get('name')).kinematic is not True:
                damping.set_damping_coefficient(prefix + joint.get('name'), float(jdamp))
    
    return system
Ejemplo n.º 9
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()