Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from controller import Robot, Keyboard, Supervisor,Emitter,Receiver,PositionSensor
- from math import atan, pi, acos, sqrt, sin, cos
- import numpy as np
- robot = Robot()
- TIMESTEP = int(robot.getBasicTimeStep())
- timestep = TIMESTEP
- X,Y,Z = 0,0,0
- angle = 0
- maxSpeed = 15 #30
- theta = [0,0,0]
- otheta = [0,0,0]
- para = [0,0,0]
- #90,3,180 works
- para[0] = 50
- para[1] = 1 #1.5 #35*maxSpeed/3600
- para[2] = 10#4
- def setSpeed(l,r):
- motor[0].setVelocity(l)
- motor[1].setVelocity(r)
- def getSpeed(ang, ang_dot):
- target = 0
- theta[0] = ang
- theta[1] += ang
- theta[2] = ang_dot
- if abs(theta[0])<0.05:
- theta[1] = 0
- speed = theta[0]*para[0]+theta[1]*para[1]+theta[2]*para[2]
- otheta[0] = theta[0]
- otheta[1] = theta[1]
- otheta[2] = theta[2]
- if abs(speed)>maxSpeed:
- speed = maxSpeed*(speed/abs(speed))
- return speed
- state = [0, 0, 0, 0]
- K = [10, -1.7, 150, 600]
- #K = [6, -0.8, 200, 350]
- #K = [7.5, -0.85, 75, 200]
- #K = [10, 0, 100, 300] # is stable to some extent. Tested for 15 minutes
- def lqrSpeed(phi, dphi,theta, theta_dot):
- state[0] = phi
- state[1] = dphi
- state[2] = theta
- state[3] = theta_dot
- d = [ K[i]*state[i] for i in range(len(K))]
- s = sum(d)
- if abs(s)>maxSpeed:
- s = maxSpeed*(s/abs(s))
- return s
- def reset_param():
- global gAng,aAng,angle,lDisRef,rDisRef,lEnc,rEnc,oldxD,speed,oT,xD
- gAng = 0
- aAng = 0
- angle = 0
- for i in range(len(motorNames)):
- motor.append(robot.getDevice(motorNames[i]))
- motor[i].setPosition(float('inf'))
- motor[i].setVelocity(0)
- lDisRef = lEnc.getValue()
- rDisRef = rEnc.getValue()
- oldxD = (lDisRef+rDisRef)*90/pi
- speed = 0
- oT = robot.getTime()
- xD = 0
- #Setup motors
- motorNames = ['leftMotor', 'rightMotor']
- motor = []
- for i in range(len(motorNames)):
- motor.append(robot.getDevice(motorNames[i]))
- motor[i].setPosition(float('inf'))
- motor[i].setVelocity(0)
- #Setup Accelerometer and Gyroscope
- accMeter = robot.getDevice('accel')
- accMeter.enable(TIMESTEP)
- gyro = robot.getDevice('gyro')
- gyro.enable(TIMESTEP)
- #Setup Encoders
- lEnc = robot.getDevice("leftEncoder")
- lEnc.enable(TIMESTEP)
- rEnc = robot.getDevice("rightEncoder")
- rEnc.enable(TIMESTEP)
- robot.step(timestep)
- #Initiate keyboard
- keyb = Keyboard()
- keyb.enable(TIMESTEP)
- #Initialize Emitter and Receiver
- emitter = robot.getDevice("emitter")
- emitter.setChannel(2)
- reciever = robot.getDevice("receiver")
- reciever.enable(timestep)
- reciever.setChannel(1)
- #Establish Proper Sync Between Emitter And Reciever
- oT = robot.getTime()
- gAng = 0
- oldxD = 0
- oldT = oT
- # uses PID or else LQR
- pid = False
- fitness = 0
- # Get reference value of encoder
- lDisRef = lEnc.getValue()
- rDisRef = rEnc.getValue()
- stop = False
- oldG = np.array([0,0,0])
- xD = 0
- previous_msg = ""
- while robot.step(timestep) != -1:
- # Data Transmission
- # 1.Get LQR Parameters and Run
- # 2.Send Back Fitness when requested
- if reciever.getQueueLength()>0:
- message = reciever.getData().decode('utf-8')
- if message=="return_fitness":
- emitter.send(str(fitness).encode('utf-8'))
- speed = 0
- for i in range(len(motorNames)):
- motor[i].setPosition(float('inf'))
- motor[i].setVelocity(0)
- reset_param()
- stop = True
- print("Robot: Fitness for ",K," is ",fitness)
- else:
- message_ = [float(param) for param in message.split(',') ]
- K = message_
- fitness = 0
- #print(K)
- stop = False
- reciever.nextPacket()
- # Run Controll Algorithm
- [x,y,z] = accMeter.getValues()
- [gx,gy,gz] = np.array(gyro.getValues())
- gAng += (gx*(robot.getTime()-oT))*180/pi
- oT = robot.getTime()
- if gy!=0:
- aAng = -atan(gz/gy)*180/pi
- else:
- aAng = 0
- if aAng>0:
- aAng = 90-aAng
- else:
- aAng = -1*(90+aAng)
- angle = 0.99*gAng + 0.01*aAng
- # Controller
- if pid:
- #print('%.2f'%gAng," vs ",'%.2f'%aAng, " VS ", '%.2f'%angle)
- speed = getSpeed(angle,gx)
- elif not(stop) :
- lDis = lEnc.getValue() - lDisRef
- rDis = rEnc.getValue() - rDisRef
- xD = (lDis+rDis)*90/pi
- if (robot.getTime()-oldT)>0:
- speed = lqrSpeed(xD,(oldxD-xD)/(robot.getTime()-oldT),angle, gx)
- else:
- speed = lqrSpeed(xD,0,angle, gx)
- oldxD = xD
- oldT = robot.getTime()
- """
- print('Theta %.3f'%angle, "\tSpeed : ",'%.3f'%speed,
- "\tIntegral : ",'%.3f'%theta[1], "\tDerivative : ",'%.3f'%theta[2],
- "\tPhi : ",'%.3f'%xD)
- """
- elif stop:
- speed = 0
- if abs(angle)<5:
- fitness += angle/5
- # Penalize when the SBR falls and favour oscillations
- if abs(angle)>50:
- fitness += (150)
- #print(speed)
- setSpeed(speed,speed)
- print("Got Out")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement