Introduce calling API to control the robot
Calling the API to Control the Robot
l For the reason that the movement and other functions of walking robots are much more complicated than wheeled robots:
1. The wheeled robot only needs to control the high and low levels of a few GPIO ports to control the movement of the robot.
2. The walking robot needs to control the angle change of a dozen servos, which involves the change of the movement direction and the generation of gait, and it needs a lot of code to realize the movement of the walking robot.
l If the code related to the motion control of the walking robot is written into `server.py` or `webServer.py`, the readability of the program will become poor, so we separate the communication from the underlying motion control program.
l The code responsible for controlling the movement of the robot is in `move.py` and `RPIServo.py` in the `server` folder.
l If you want to change the communication method of the robot, or want to write a program to control the robot, and do not want to reconstruct the code of the underlying motion control and gait generation, you can refer to the API introduced in this chapter to control the robot. The content introduced in this chapter is also the method used by our `webServer.py` or `server.py` to control the robot movement.
l First of all, your program needs to be placed in the same file directory as `move.py`and `RPIservo.py`. Importing move.py and RPIservo.p:
import move import RPIservo |
l After importing, the related thread that controls the robot's gait will be automatically opened in the background. If there is no command, the thread will be suspended. Put all servos in the initial position in RPIservo.py, the default is `300`, the value will change after fine adjustment of the servo position:
init_pwm0 = 300 init_pwm1 = 300 init_pwm2 = 300 init_pwm3 = 300 init_pwm4 = 300 init_pwm5 = 300 init_pwm6 = 300 init_pwm7 = 300 init_pwm8 = 300 init_pwm9 = 300 init_pwm10 = 300 init_pwm11 = 300 init_pwm12 = 300 init_pwm13 = 300 init_pwm14 = 300 init_pwm15 = 300 |
l The code responsible for initialization is in move.py, call the initial value init_pwm in RPIservo.py through exec, use the for loop to take out all the initial values and assign it to pwm0, pwm1... variables
1. for i in range(0,16): 2. exec('pwm%d=RPIservo.init_pwm%d'%(i,i)) 3. 4. def init_all(): 5. pwm.set_pwm(0, 0, pwm0) 6. pwm.set_pwm(1, 0, pwm1) 7. pwm.set_pwm(2, 0, pwm2) 8. pwm.set_pwm(3, 0, pwm3) 9. 10. pwm.set_pwm(4, 0, pwm4) 11. pwm.set_pwm(5, 0, pwm5) 12. pwm.set_pwm(6, 0, pwm6) 13. pwm.set_pwm(7, 0, pwm7) 14. 15. pwm.set_pwm(8, 0, pwm8) 16. pwm.set_pwm(9, 0, pwm9) 17. pwm.set_pwm(10, 0, pwm10) 18. pwm.set_pwm(11, 0, pwm11) 19. 20. pwm.set_pwm(12, 0, pwm12) 21. pwm.set_pwm(13, 0, pwm13) 22. pwm.set_pwm(14, 0, pwm14) 23. pwm.set_pwm(15, 0, pwm15) 24. init_all() |
l In webserver.py, the robotCtrl() function is used to control the robot to move forward, backward, turn left, turn right, and rotate the two-degree-of-freedom camera platform:
1. def robotCtrl(command_input, response): 2. global direction_command, turn_command 3. if 'forward' == command_input: #move forward 4. direction_command = 'forward' 5. move.commandInput(direction_command) #move backward 6. elif 'backward' == command_input: 7. direction_command = 'backward' 8. move.commandInput(direction_command) 9. elif 'DS' in command_input: #stop 10. direction_command = 'stand' 11. move.commandInput(direction_command) 12. elif 'left' == command_input: #turn left 13. turn_command = 'left' 14. move.commandInput(turn_command) 15. elif 'right' == command_input: #turn right 16. turn_command = 'right' 17. move.commandInput(turn_command) 18. elif 'TS' in command_input: #stop 19. turn_command = 'no' 20. move.commandInput(turn_command) 21. elif 'lookleft' == command_input: # the platform turns left 22. P_sc.singleServo(12, 1, 7) 23. elif 'lookright' == command_input: #the platform turns right 24. P_sc.singleServo(12,-1, 7) 25. elif 'LRstop' in command_input: #the platform stops turning left and right 26. P_sc.stopWiggle() 27. elif 'up' == command_input: #platform turns upward 28. T_sc.singleServo(13, -1, 7) 29. elif 'down' == command_input: #platform turns downward 30. T_sc.singleServo(13, 1, 7) 31. elif 'UDstop' in command_input: #the platform stops turning up and down 32. T_sc.stopWiggle() |
l In webserver.py, use the functionSelect() function to start the action of the robot:
1. def functionSelect(command_input, response): 2. global direction_command, turn_command, SmoothMode, steadyMode, functionMode 3. if 'scan' == command_input: 4. pass 5. elif 'findColor' == command_input: 6. flask_app.modeselect('findColor') 7. elif 'motionGet' == command_input: # Moving object detection 8. flask_app.modeselect('watchDog') 9. elif 'stopCV' == command_input: 10. flask_app.modeselect('none') 11. switch.switch(1,0) 12. switch.switch(2,0) 13. switch.switch(3,0) 14. elif 'KD' == command_input: #Self-balancing 15. move.commandInput(command_input) 16. elif 'automaticOff' == command_input: # switch to default fast gait 17. move.commandInput(command_input) 18. elif 'automatic' == command_input: # switch to slow gait 19. move.commandInput(command_input) 20. elif 'trackLine' == command_input: # track line on 21. flask_app.modeselect('findlineCV') 22. elif 'trackLineOff' == command_input: # track line off 23. flask_app.modeselect('none') 24. elif 'speech' == command_input: # turn on the alarm light 25. RL.police() 26. elif 'speechOff' == command_input: # turn off the alarm light 27. RL.pause() |
l We control the robot to move forward, move backward, turn left, turn right, switch between fast and slow gait, and maintain self-balance in move.py. When the webserver, py receives the forward command "command_input", it will call the commandInput() function in move.py. When the commandInput() function receives an instruction, it starts a thread, calls the corresponding action, and executes a fast gait by default, such as forward moving, backward moving, left turn, and right turn:
1. def move_thread(): 2. global step_set 3. stand_stu = 1 4. if not steadyMode: 5. ''''' 6. #The default value of steadyMode is equal to True when the initial value is 0, and then else is not executed. When executing the self-balancing action, setting the initial value of steadyMode to 1, which is if not steadyMode: equal to False, then it will execute else. 7. ''' 8. if direction_command == 'forward' and turn_command == 'no': 9. if SmoothMode: 10. ''''' 11. #The default value of SmoothMode is equal to False when the initial value is 0, and it will execute else; when switching to slow gait, setting the initial value to 1, you will get if SmoothMode: equal to True, then it will execute dove (). 12. ''' 13. dove(step_set,35,0.001,DPI,'no') # slow gait of moving forward 14. step_set += 1 15. if step_set == 5: 16. step_set = 1 17. else: 18. move(step_set, 35, 'no') # fast gait of moving forward 19. time.sleep(0.1) 20. step_set += 1 21. if step_set == 5: 22. step_set = 1 23. elif direction_command == 'backward' and turn_command == 'no': 24. if SmoothMode: 25. dove(step_set,-35,0.001,DPI,'no') #slow gait of moving backward 26. step_set += 1 27. if step_set == 5: 28. step_set = 1 29. else: 30. move(step_set, -35, 'no') # fast gait of moving backward 31. time.sleep(0.1) 32. step_set += 1 33. if step_set == 5: 34. step_set = 1 35. else: 36. pass 37. if turn_command != 'no': # gait of turning left and right 38. if SmoothMode: 39. dove(step_set,35,0.001,DPI,turn_command) 40. step_set += 1 41. if step_set == 5: 42. step_set = 1 43. else: 44. move(step_set, 35, turn_command) 45. time.sleep(0.1) 46. step_set += 1 47. if step_set == 5: 48. step_set = 1 49. else: 50. pass 51. if turn_command == 'no' and direction_command == 'stand': 52. stand() 53. step_set = 1 54. pass 55. else: #Self-balancing 56. steady_X() 57. steady() 58. 59. class RobotM(threading.Thread): 60. def __init__(self, *args, **kwargs): 61. super(RobotM, self).__init__(*args, **kwargs) 62. self.__flag = threading.Event() #The default flag is False, set the flag to True when calling set() self.__flag.clear() 63. def pause(self): 64. #print('......................pause..........................') 65. self.__flag.clear() 66. def resume(self): 67. self.__flag.set() 68. def run(self): 69. while 1: 70. self.__flag.wait() #wait for set() 71. move_thread() 72. pass 73. rm = RobotM() 74. rm.start() 75. rm.pause() 76. 77. def commandInput(command_input): 78. global direction_command, turn_command, SmoothMode, steadyMode 79. if 'forward' == command_input: 80. direction_command = 'forward' #move forward 81. rm.resume() 82. elif 'backward' == command_input: 83. direction_command = 'backward' #move backward 84. rm.resume() 85. elif 'stand' in command_input: 86. direction_command = 'stand' #stand at attention 87. rm.pause() 88. elif 'left' == command_input: 89. turn_command = 'left' #turn left 90. rm.resume() 91. elif 'right' == command_input: 92. turn_command = 'right' #turn right 93. rm.resume() 94. elif 'no' in command_input: #stop 95. turn_command = 'no' 96. rm.pause() 97. elif 'automaticOff' == command_input: #Switch to fast gait 98. SmoothMode = 0 99. steadyMode = 0 100. rm.pause() 101. elif 'automatic' == command_input: #Switch to slow gait 102. rm.resume() 103. SmoothMode = 1 104. elif 'KD' == command_input: #Self-balancing 105. steadyMode = 1 106. rm.resume() |