feat: v4
This commit is contained in:
		
							
								
								
									
										212
									
								
								simulator.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								simulator.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,212 @@
 | 
			
		||||
import os
 | 
			
		||||
import argparse
 | 
			
		||||
import math
 | 
			
		||||
import time
 | 
			
		||||
import pybullet as p
 | 
			
		||||
if __package__ is None or __package__ == '':
 | 
			
		||||
    import control
 | 
			
		||||
else:
 | 
			
		||||
    from . import control
 | 
			
		||||
 | 
			
		||||
t = 0.
 | 
			
		||||
dt = 0.01
 | 
			
		||||
dirname = os.path.dirname(__file__) + '/models/'
 | 
			
		||||
n_motors = 0
 | 
			
		||||
jointsMap = []
 | 
			
		||||
 | 
			
		||||
def init():
 | 
			
		||||
    """Initialise le simulateur"""
 | 
			
		||||
    # Instanciation de Bullet
 | 
			
		||||
    physicsClient = p.connect(p.GUI)
 | 
			
		||||
    p.setGravity(0, 0, -10)
 | 
			
		||||
 | 
			
		||||
    # Chargement du sol
 | 
			
		||||
    planeId = p.loadURDF(dirname+'/plane.urdf')
 | 
			
		||||
 | 
			
		||||
    p.setPhysicsEngineParameter(fixedTimeStep=dt)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def loadModel(name, fixed=False, startPos=[0., 0., 0.1], startOrientation=[0., 0., 0.]):
 | 
			
		||||
    """Charge un modèle"""
 | 
			
		||||
    startOrientation = p.getQuaternionFromEuler(startOrientation)
 | 
			
		||||
    model = p.loadURDF(dirname+"/"+name+"/robot.urdf",
 | 
			
		||||
                       startPos, startOrientation, useFixedBase=fixed)
 | 
			
		||||
 | 
			
		||||
    return model
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def setJoints(robot, joints):
 | 
			
		||||
    """Définis les angles cibles pour les moteurs du robot
 | 
			
		||||
 | 
			
		||||
    Arguments:
 | 
			
		||||
        int -- identifiant du robot
 | 
			
		||||
        joints {list} -- liste des positions cibles (rad)
 | 
			
		||||
    """
 | 
			
		||||
    global jointsMap
 | 
			
		||||
    
 | 
			
		||||
    for k in range(len(joints)):
 | 
			
		||||
        jointInfo = p.getJointInfo(robot, jointsMap[k])
 | 
			
		||||
        p.setJointMotorControl2(
 | 
			
		||||
            robot, jointInfo[0], p.POSITION_CONTROL, joints[k])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def inverseControls(name='', x_default=0.15, y_default=0.):
 | 
			
		||||
    target_x = p.addUserDebugParameter(
 | 
			
		||||
        '%starget_x' % name, -0.3, 0.3, x_default)
 | 
			
		||||
    target_y = p.addUserDebugParameter(
 | 
			
		||||
        '%starget_y' % name, -0.3, 0.3, y_default)
 | 
			
		||||
    target_z = p.addUserDebugParameter('%starget_z' % name, -0.3, 0.3, 0.)
 | 
			
		||||
    target = loadModel('target2', True)
 | 
			
		||||
 | 
			
		||||
    return target_x, target_y, target_z, target
 | 
			
		||||
 | 
			
		||||
def directControls():
 | 
			
		||||
    alpha = p.addUserDebugParameter('alpha', -math.pi, math.pi, 0)
 | 
			
		||||
    beta = p.addUserDebugParameter('beta', -math.pi, math.pi, 0)
 | 
			
		||||
    gamma = p.addUserDebugParameter('gamma', -math.pi, math.pi, 0)
 | 
			
		||||
    target = loadModel('target2', True)
 | 
			
		||||
 | 
			
		||||
    return alpha, beta, gamma, target
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def inverseUpdate(controls):
 | 
			
		||||
    x = p.readUserDebugParameter(controls[0])
 | 
			
		||||
    y = p.readUserDebugParameter(controls[1])
 | 
			
		||||
    z = p.readUserDebugParameter(controls[2])
 | 
			
		||||
    p.resetBasePositionAndOrientation(
 | 
			
		||||
        controls[3], [x, y, z + floatHeight], p.getQuaternionFromEuler([0, 0, 0]))
 | 
			
		||||
 | 
			
		||||
    return x, y, z
 | 
			
		||||
 | 
			
		||||
def tick():
 | 
			
		||||
    global t
 | 
			
		||||
 | 
			
		||||
    t += dt
 | 
			
		||||
    p.stepSimulation()
 | 
			
		||||
    time.sleep(dt)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    # Arguments
 | 
			
		||||
    parser = argparse.ArgumentParser(prog="Quadruped")
 | 
			
		||||
    parser.add_argument('-m', type=str, help='Mode', default='motors')
 | 
			
		||||
    parser.add_argument('-r', type=str, help='Robot', default='quadruped')
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
    mode = args.m
 | 
			
		||||
    robot = args.r
 | 
			
		||||
 | 
			
		||||
    if mode not in ['motors', 'sandbox', 'direct', 'inverse', 'draw', 'legs', 'walk']:
 | 
			
		||||
        print('Le mode %s est inconnu' % mode)
 | 
			
		||||
        exit(1)
 | 
			
		||||
 | 
			
		||||
    init()
 | 
			
		||||
    fixed = False
 | 
			
		||||
    floatHeight = 0.15
 | 
			
		||||
 | 
			
		||||
    if robot == 'quadruped':
 | 
			
		||||
        oneLegStartPos = [-0.04, 0., floatHeight]
 | 
			
		||||
        oneLegstartOrientation = [0., 0., math.pi + math.pi/4]
 | 
			
		||||
        n_motors = 12
 | 
			
		||||
        jointsMap = [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14]
 | 
			
		||||
    else:
 | 
			
		||||
        oneLegstartOrientation = [0., 0., -math.pi/2]
 | 
			
		||||
        oneLegStartPos = [-0.079, 0.032, floatHeight]
 | 
			
		||||
        n_motors = 18
 | 
			
		||||
        jointsMap = list(range(18))
 | 
			
		||||
 | 
			
		||||
    startPos = [0., 0., floatHeight]
 | 
			
		||||
    startOrientation = [0., 0., 0.]
 | 
			
		||||
 | 
			
		||||
    if mode == 'motors':
 | 
			
		||||
        motors_sliders = []
 | 
			
		||||
        for k in range(n_motors):
 | 
			
		||||
            motors_sliders.append(p.addUserDebugParameter(
 | 
			
		||||
                "motor_%d" % k, -math.pi, math.pi, 0.))
 | 
			
		||||
    elif mode == 'inverse' or mode == 'direct':
 | 
			
		||||
        fixed = True
 | 
			
		||||
        startOrientation = oneLegstartOrientation
 | 
			
		||||
        startPos = oneLegStartPos
 | 
			
		||||
        leg = inverseControls() if mode == 'inverse' else directControls()
 | 
			
		||||
    elif mode == 'draw':
 | 
			
		||||
        fixed = True
 | 
			
		||||
        startOrientation = oneLegstartOrientation
 | 
			
		||||
        startPos = oneLegStartPos
 | 
			
		||||
        lastLine = None
 | 
			
		||||
    elif mode == 'legs':
 | 
			
		||||
        fixed = True
 | 
			
		||||
        legs = []
 | 
			
		||||
        if robot == 'quadruped':
 | 
			
		||||
            legs = [
 | 
			
		||||
                inverseControls('leg1_', -0.15, 0.15),
 | 
			
		||||
                inverseControls('leg2_', -0.15, -0.15),
 | 
			
		||||
                inverseControls('leg3_', 0.15, -0.15),
 | 
			
		||||
                inverseControls('leg4_', 0.15, 0.15)
 | 
			
		||||
            ]
 | 
			
		||||
        else:
 | 
			
		||||
            legs = [
 | 
			
		||||
                inverseControls('leg1_', 0.05, 0.24),
 | 
			
		||||
                inverseControls('leg2_', -0.05, 0.24),
 | 
			
		||||
                inverseControls('leg3_', -0.24, 0),
 | 
			
		||||
                inverseControls('leg4_', -0.05, -0.24),
 | 
			
		||||
                inverseControls('leg5_', 0.05, -0.24),
 | 
			
		||||
                inverseControls('leg6_', 0.24, 0.)
 | 
			
		||||
            ]       
 | 
			
		||||
        
 | 
			
		||||
    elif mode == 'walk':
 | 
			
		||||
        speed_x = p.addUserDebugParameter('speed_x', -0.2, 0.2, 0.0)
 | 
			
		||||
        speed_y = p.addUserDebugParameter('speed_y', -0.2, 0.2, 0.0)
 | 
			
		||||
        speed_rotation = p.addUserDebugParameter(
 | 
			
		||||
            'speed_rotation', -0.5, 0.5, 0.)
 | 
			
		||||
    elif mode == 'sandbox':
 | 
			
		||||
        print('Mode bac à sable...')
 | 
			
		||||
 | 
			
		||||
    robot = loadModel(robot, fixed, startPos, startOrientation)
 | 
			
		||||
 | 
			
		||||
    # Boucle principale
 | 
			
		||||
    while True:
 | 
			
		||||
        if mode == 'motors':
 | 
			
		||||
            joints = []
 | 
			
		||||
            for entry in motors_sliders:
 | 
			
		||||
                joints.append(p.readUserDebugParameter(entry))
 | 
			
		||||
        elif mode == 'inverse':
 | 
			
		||||
            joints = control.inverse(*inverseUpdate(leg)) + [0]*(n_motors-3)
 | 
			
		||||
        elif mode == 'direct':
 | 
			
		||||
            alpha_slider, beta_slider, gamma_slider, target = leg
 | 
			
		||||
            alpha = p.readUserDebugParameter(alpha_slider)
 | 
			
		||||
            beta = p.readUserDebugParameter(beta_slider)
 | 
			
		||||
            gamma = p.readUserDebugParameter(gamma_slider)
 | 
			
		||||
            joints = [alpha, beta, gamma] + [0]*(n_motors-3)
 | 
			
		||||
            x, y, z = control.direct(alpha, beta, gamma)
 | 
			
		||||
            p.resetBasePositionAndOrientation(target, [x, y, z + floatHeight],
 | 
			
		||||
                p.getQuaternionFromEuler([0, 0, 0]))
 | 
			
		||||
        elif mode == 'draw':
 | 
			
		||||
            joints = control.draw(t) + [0]*(n_motors-3)
 | 
			
		||||
 | 
			
		||||
            def getLegTip():
 | 
			
		||||
                res = p.getLinkState(robot, 3)
 | 
			
		||||
                return res[0]
 | 
			
		||||
 | 
			
		||||
            if lastLine is None:
 | 
			
		||||
                lastLine = time.time(), getLegTip()
 | 
			
		||||
            elif time.time() - lastLine[0] > 0.1:
 | 
			
		||||
                tip = getLegTip()
 | 
			
		||||
                p.addUserDebugLine(lastLine[1], tip, (1., 0, 0), 2., 10.)
 | 
			
		||||
                lastLine = time.time(), tip
 | 
			
		||||
        elif mode == 'legs':
 | 
			
		||||
            legs_xyz = [
 | 
			
		||||
                inverseUpdate(leg) for leg in legs
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
            joints = control.legs(legs_xyz)
 | 
			
		||||
        elif mode == 'walk':
 | 
			
		||||
            x = p.readUserDebugParameter(speed_x)
 | 
			
		||||
            y = p.readUserDebugParameter(speed_y)
 | 
			
		||||
            rotation = p.readUserDebugParameter(speed_rotation)
 | 
			
		||||
            joints = control.walk(t, x, y, rotation)
 | 
			
		||||
        elif mode == 'sandbox':
 | 
			
		||||
            joints = control.sandbox(t)
 | 
			
		||||
 | 
			
		||||
        # Envoi des positions cibles au simulateur
 | 
			
		||||
        setJoints(robot, joints)
 | 
			
		||||
 | 
			
		||||
        # Mise à jour de la simulation
 | 
			
		||||
        tick()
 | 
			
		||||
		Reference in New Issue
	
	Block a user