You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
9.0KB

  1. #!/usr/bin/env python2
  2. #######################################################################
  3. # Aufgabe 1 #
  4. #######################################################################
  5. import pygame
  6. import math
  7. import argparse, sys
  8. import servo_ctrl
  9. width = 400
  10. height = 200
  11. freq = 50 # Sets the frequency of input procession
  12. delta = 1.0 / freq # time per step
  13. acc = 2.6 # Max acceleration of the car (per sec.)
  14. dec = 4.5 # Max deceleration of the car (per sec.)
  15. frict = -1 # max friction
  16. angle_acc = 300 # max change of angle (per sec.)
  17. speed_cur = 0
  18. angle_cur = 0
  19. V_MAX = 11 # Maximale Geswindigkeit 11 m/s
  20. ANGLE_MAX = 45
  21. mouse_ctrl = False
  22. v_step = True # Stufenweises regel der Beschlunigung in beide Richtungen
  23. m_step = True
  24. # vars for testmode
  25. is_testmode_enabled = True
  26. testmode_vars = {'is_servo_active': False}
  27. # vars for car
  28. motor = None
  29. streeting = None
  30. # start main pygame event processing loop here
  31. pygame.display.init()
  32. # set up the pygame screen enviroment
  33. screen = pygame.display.set_mode((width, height))
  34. # get a clock to generate frequent behaviour
  35. clock = pygame.time.Clock()
  36. # States of the keys
  37. keystates = {
  38. 'quit': False,
  39. 'accelerate': False,
  40. 'decelerate': False,
  41. 'reset': False,
  42. 'accelerate_angle_right': False,
  43. 'accelerate_angle_left': False,
  44. 'acceleration_mouse': False,
  45. 'mouse_ctrl': False,
  46. }
  47. running = True
  48. # Functions for exercises
  49. def calculate_acceleration(speed, acc):
  50. sigma = 2.5
  51. mu = V_MAX / 2
  52. return acc * (1 - 0.5 * (1 + (math.erf((abs(speed) - mu) / (math.sqrt(2 * sigma**2))))))
  53. def calculate_friction(speed, f):
  54. # TODO hier stimmt was nicht
  55. sigma = 4
  56. mu = V_MAX / 2
  57. return (f/2) * (1 + (math.erf((abs(speed) - mu) / (math.sqrt(2 * sigma**2)))))
  58. def toggle_mouse_ctrl():
  59. global mouse_ctrl
  60. mouse_ctrl= not mouse_ctrl
  61. def mouse_ctrl_calc_velocity(pos):
  62. global height, V_MAX
  63. x, y = pos
  64. rel_y = y - (height/2)
  65. return -1 * (rel_y / (height/2.0)) * V_MAX
  66. def mouse_ctrl_calc_angle(pos):
  67. global width, ANGLE_MAX
  68. x, y = pos
  69. rel_x = x - (width/2.0)
  70. return (rel_x / (width/2)) * ANGLE_MAX
  71. if __name__ == "__main__":
  72. parser = argparse.ArgumentParser(description='IoT Lab script')
  73. parser.add_argument('--notest', action='store_true', default=False)
  74. args = parser.parse_args()
  75. if not args.notest:
  76. print "Running in testmode."
  77. else:
  78. is_testmode_enabled = False
  79. motor = Motor(1)
  80. streeting = Steering(2)
  81. try:
  82. while running:
  83. # set clock frequency
  84. clock.tick(freq);
  85. # save the last speed 4 analysis
  86. last = speed_cur
  87. # process input events
  88. for event in pygame.event.get():
  89. # exit on quit
  90. if event.type == pygame.QUIT:
  91. running = False
  92. # check for key down events (press)
  93. if event.type == pygame.KEYDOWN:
  94. if event.key == pygame.K_q:
  95. keystates['quit'] = True
  96. elif event.key == pygame.K_w:
  97. keystates['accelerate'] = True
  98. elif event.key == pygame.K_s:
  99. keystates['decelerate'] = True
  100. elif event.key == pygame.K_d:
  101. keystates['accelerate_angle_right'] = True
  102. elif event.key == pygame.K_a:
  103. keystates['accelerate_angle_left'] = True
  104. elif event.key == pygame.K_m:
  105. keystates['mouse_ctrl'] = True
  106. elif event.key == pygame.K_r:
  107. keystates['reset'] = True
  108. # check for key up events (release)
  109. if event.type == pygame.KEYUP:
  110. if event.key == pygame.K_q:
  111. keystates['quit'] = False
  112. elif event.key == pygame.K_w:
  113. v_step = True
  114. testmode_vars['is_servo_active'] = False
  115. keystates['accelerate'] = False
  116. elif event.key == pygame.K_s:
  117. v_step = True
  118. testmode_vars['is_servo_active'] = False
  119. keystates['decelerate'] = False
  120. elif event.key == pygame.K_d:
  121. keystates['accelerate_angle_right'] = False
  122. elif event.key == pygame.K_a:
  123. keystates['accelerate_angle_left'] = False
  124. elif event.key == pygame.K_m:
  125. keystates['mouse_ctrl'] = False
  126. m_step = True
  127. elif event.key == pygame.K_r:
  128. v_step = True
  129. keystates['reset'] = False
  130. if event.type == pygame.MOUSEBUTTONDOWN:
  131. # linke maustaste
  132. if event.button == 1:
  133. testmode_vars['is_servo_active'] = True
  134. keystates['acceleration_mouse'] = True
  135. if event.type == pygame.MOUSEBUTTONUP:
  136. if event.button == 1:
  137. testmode_vars['is_servo_active'] = False
  138. keystates['acceleration_mouse'] = False
  139. # do something about the key states here, now that the event queue has been processed
  140. if keystates['quit']:
  141. running = False
  142. if keystates['reset']:
  143. # reset
  144. speed_cur = 0
  145. angle_cur = 0
  146. mouse_ctrl = False
  147. if keystates['mouse_ctrl'] and m_step:
  148. # beim umstellen zur maus steuerung und geschw. zuruecksetzen
  149. speed_cur = 0
  150. angle_cur = 0
  151. toggle_mouse_ctrl()
  152. m_step = False
  153. print "Is mouse control enabled?: " + str(mouse_ctrl)
  154. # Calculate valeues for control types
  155. if mouse_ctrl:
  156. pos = pygame.mouse.get_pos()
  157. angle_cur = mouse_ctrl_calc_angle(pos)
  158. if keystates['acceleration_mouse']:
  159. speed_cur = mouse_ctrl_calc_velocity(pos)
  160. elif not is_testmode_enabled:
  161. speed_cur = 0
  162. else:
  163. if keystates['accelerate']: # and v_step:
  164. # Beschleunigen
  165. v_step = False
  166. if is_testmode_enabled:
  167. calc_acc = calculate_acceleration(speed_cur, acc)
  168. speed_cur = min(V_MAX, speed_cur + calc_acc)
  169. testmode_vars['is_servo_active'] = True
  170. else:
  171. speed_cur = min(V_MAX, speed_cur + acc)
  172. if keystates['decelerate']: # and v_step:
  173. # abbremsen
  174. v_step = False
  175. if is_testmode_enabled:
  176. calc_dec = calculate_acceleration(speed_cur, dec)
  177. speed_cur = max(-1 * V_MAX, speed_cur - calc_dec)
  178. testmode_vars['is_servo_active'] = True
  179. else:
  180. speed_cur = max(-1 * V_MAX, speed_cur - dec)
  181. if keystates['accelerate_angle_right']:
  182. # ist das so richtig angle_acc = 300? TODO
  183. angle_cur = min(ANGLE_MAX, angle_cur + angle_acc)
  184. if keystates['accelerate_angle_left']:
  185. # ist das so richtig angle_acc = 300? TODO
  186. angle_cur = max(-1 * ANGLE_MAX, angle_cur - angle_acc)
  187. if not keystates['accelerate_angle_left'] and not keystates['accelerate_angle_right']:
  188. angle_cur = 0
  189. if not is_testmode_enabled and (not keystates['accelerate'] and not keystates['decelerate']):
  190. # Wenn nicht im testmode und weger beschl noch gebremst wird
  191. speed_cur = 0
  192. if is_testmode_enabled:
  193. if not testmode_vars['is_servo_active']:
  194. speed_cur = min(0, speed_cur - calculate_friction(speed_cur, -1))
  195. else:
  196. motor.set_speed(speed_cur)
  197. steering.set_angle(angle_cur)
  198. # Hier denn Wete an servos geben TODO
  199. print("({},{} --> {})".format(speed_cur, angle_cur, (speed_cur - last) / delta)) + ", Servo_active: " + str(testmode_vars['is_servo_active'])
  200. except KeyboardInterrupt:
  201. print "Exiting through keyboard event (CTRL + C)"
  202. # gracefully exit pygame here
  203. pygame.quit()