Advertisement
lencH

Besiege Python Drone

Sep 19th, 2016
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.79 KB | None | 0 0
  1. """BLOCK GUIDS"""
  2. starting_block = Besiege.GetBlock("c62db254-76f6-4374-ae36-607808eace52")
  3. front_left_rotor = Besiege.GetBlock("1b920418-8c49-491b-aeca-3e5c16d35964")
  4. front_right_rotor = Besiege.GetBlock("7d1b703b-d46f-4a3b-8013-05441cbb736f")
  5. rear_left_rotor = Besiege.GetBlock("84e3bbfa-345a-4494-9144-ffeb85ff6a9b")
  6. rear_right_rotor = Besiege.GetBlock("adb019f0-3b1f-4825-95cb-9a18d8a1caf1")
  7.  
  8. """PID TUNING"""
  9. ALTITUDE_PID = {"p" : 1.5, "i" : 1, "d" : 0.5, "max" : 5}
  10. PITCH_PID = {"p" : 1, "i" : 0.1, "d" : 0.5, "max" : 90}
  11. ROLL_PID = {"p" : 1, "i" : 0.1, "d" : 0.5, "max" : 90}
  12.  
  13. """CONSTANTS DEFINITIONS"""
  14. HOVER_SPEED = 2
  15. HOLD_ALTITUDE = True
  16.  
  17. """ANGULAR PID CONTROLLER CLASS DEFINITION"""
  18. class AngularController:
  19.     def __init__(self, p, i, d, max):
  20.         sum = float(p + i + d)
  21.         self.p = p / sum
  22.         self.i = i / sum
  23.         self.d = d / sum
  24.         self.err = float(0)
  25.         self.int = float(0)
  26.         self.der = float(0)
  27.         self.max = float(max)
  28.         self.first_call = True
  29.         self.on_target = False
  30.         self.last_time = None
  31.         self.last_current = None
  32.  
  33.     def control(self, current, target):
  34.         time = Besiege.GetTime()
  35.         output = 0
  36.         if self.first_call:
  37.             self.first_call = False
  38.         else:
  39.             self.delta_time = (time - self.last_time)
  40.             self.err = clamp(Mathf.DeltaAngle(current, target), self.p * self.max * -1, self.p * self.max)
  41.             self.int = clamp(self.int + self.err * self.delta_time, self.i * self.max * -1, self.i * self.max)
  42.             self.der = Mathf.DeltaAngle(current, self.last_current) * self.delta_time
  43.             output = (self.err * self.p) + (self.int * self.i) + (self.der * self.d)
  44.             self.on_target = abs(self.err / self.max) < 0.05 and abs(self.der / self.max) < 0.05
  45.         self.last_current = current
  46.         self.last_time = time
  47.         output = clamp(output, self.max * -1, self.max) / self.max
  48.         return output
  49.  
  50. """LINEAR PID CONTROLLER CLASS DEFINITION"""
  51. class LinearController:
  52.     def __init__(self, p, i, d, max):
  53.         sum = float(p + i + d)
  54.         self.p = p / sum
  55.         self.i = i / sum
  56.         self.d = d / sum
  57.         self.err = float(0)
  58.         self.int = float(0)
  59.         self.der = float(0)
  60.         self.max = float(max)
  61.         self.first_call = True
  62.         self.on_target = False
  63.         self.last_time = None
  64.         self.last_current = None
  65.  
  66.     def control(self, current, target):
  67.         time = Besiege.GetTime()
  68.         output = 0
  69.         if self.first_call:
  70.             self.first_call = False
  71.         else:
  72.             self.delta_time = (time - self.last_time)
  73.             self.err = clamp(current - target, self.p * self.max * -1, self.p * self.max)
  74.             self.int = clamp(self.int + self.err * self.delta_time, self.i * self.max * -1, self.i * self.max)
  75.             self.der = (current - self.last_current) * self.delta_time
  76.             output = (self.err * self.p) + (self.int * self.i) + (self.der * self.d)
  77.             self.on_target = abs(self.err / self.max) < 0.05 and abs(self.der / self.max) < 0.05
  78.         self.last_current = current
  79.         self.last_time = time
  80.         output = clamp(output, self.max * -1, self.max) / self.max
  81.         return output
  82.  
  83.  
  84. """GLOBAL VARIABLES"""
  85. target_altitude = starting_block.Position.y
  86.  
  87. """PID CONTROLLERS"""
  88. drone_altitude_controller = LinearController(ALTITUDE_PID["p"], ALTITUDE_PID["i"], ALTITUDE_PID["d"], ALTITUDE_PID["max"])
  89. drone_pitch_controller = AngularController(PITCH_PID["p"], PITCH_PID["i"], PITCH_PID["d"], PITCH_PID["max"])
  90. drone_roll_controller = AngularController(ROLL_PID["p"], ROLL_PID["i"], ROLL_PID["d"], ROLL_PID["max"])
  91.  
  92. """AUTOMATIC TOGGLES"""
  93. front_left_rotor.SetToggleMode("AUTOMATIC", True)
  94. front_right_rotor.SetToggleMode("AUTOMATIC", True)
  95. rear_left_rotor.SetToggleMode("AUTOMATIC", True)
  96. rear_right_rotor.SetToggleMode("AUTOMATIC", True)
  97.  
  98. def Update():
  99.     global target_altitude
  100.  
  101.     target_pitch = Input.GetAxis("Vertical") * 15
  102.     target_roll = Input.GetAxis("Horizontal") * -15
  103.  
  104.     if Input.GetKey(KeyCode.I):
  105.         target_altitude += 5 * Time.deltaTime
  106.     if Input.GetKey(KeyCode.K):
  107.         target_altitude -= 5 * Time.deltaTime
  108.  
  109.     position = starting_block.Position
  110.     rotation = starting_block.EulerAngles
  111.  
  112.     altitude_adjustment = - drone_altitude_controller.control(position.y, target_altitude)
  113.     pitch_adjustment = drone_pitch_controller.control(rotation.x, target_pitch)
  114.     roll_adjustment = drone_roll_controller.control(rotation.z, target_roll)
  115.  
  116.     front_left_speed = HOVER_SPEED + HOVER_SPEED * (altitude_adjustment - pitch_adjustment - roll_adjustment)
  117.     front_right_speed = HOVER_SPEED + HOVER_SPEED * (altitude_adjustment - pitch_adjustment + roll_adjustment)
  118.     rear_left_speed = HOVER_SPEED + HOVER_SPEED * (altitude_adjustment + pitch_adjustment - roll_adjustment)
  119.     rear_right_speed = HOVER_SPEED + HOVER_SPEED * (altitude_adjustment + pitch_adjustment + roll_adjustment)
  120.  
  121.     front_left_rotor.SetSliderValue("SPEED", front_left_speed)
  122.     front_right_rotor.SetSliderValue("SPEED", front_right_speed)
  123.     rear_left_rotor.SetSliderValue("SPEED", rear_left_speed)
  124.     rear_right_rotor.SetSliderValue("SPEED", rear_right_speed)
  125.  
  126.     Besiege.Watch("target altitude", target_altitude)
  127.     Besiege.Watch("current altitude", position.y)
  128.     Besiege.Watch("altitude_adjustment", altitude_adjustment)
  129.     Besiege.Watch("target pitch", target_pitch)
  130.     Besiege.Watch("current pitch", rotation.x)
  131.     Besiege.Watch("pitch_adjustment", pitch_adjustment)
  132.     Besiege.Watch("target roll", target_roll)
  133.     Besiege.Watch("current roll", rotation.z)
  134.     Besiege.Watch("roll_adjustment", roll_adjustment)
  135.  
  136. def clamp(value, minvalue, maxvalue):
  137.     return max(min(value, maxvalue), minvalue)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement