Makes the `GoPiGo3`_ robot turn at a specific angle while staying in the same spot. :param float degrees: The angle in degress at which the `GoPiGo3`_ has to turn. For rotating the robot to the left, ``degrees`` has to negative, and make it turn to the right, ``degrees`` has to be
(self, degrees, blocking=True)
| 752 | return average |
| 753 | |
| 754 | def turn_degrees(self, degrees, blocking=True): |
| 755 | """ |
| 756 | Makes the `GoPiGo3`_ robot turn at a specific angle while staying in the same spot. |
| 757 | |
| 758 | :param float degrees: The angle in degress at which the `GoPiGo3`_ has to turn. For rotating the robot to the left, ``degrees`` has to negative, and make it turn to the right, ``degrees`` has to be positive. |
| 759 | :param boolean blocking = True: Set it as a blocking or non-blocking method. |
| 760 | |
| 761 | ``blocking`` parameter can take the following values: |
| 762 | |
| 763 | * ``True`` so that the method will wait for the `GoPiGo3`_ robot to finish moving. |
| 764 | * ``False`` so that the method will exit immediately while the `GoPiGo3`_ robot will continue moving. |
| 765 | |
| 766 | In order to better understand what does this method do, let's take a look at the following graphical representation. |
| 767 | |
| 768 | .. image:: ../images/gpg3_robot.svg |
| 769 | |
| 770 | In the image, we have multiple identifiers: |
| 771 | |
| 772 | * The "*heading*": it represents the robot's heading. By default, "rotating" the robot by 0 degrees is going to make the robot stay in place. |
| 773 | * The "*wheel circle circumference*": this is the circle that's described by the 2 motors moving in opposite direction. |
| 774 | * The "*GoPiGo3*": the robot we're playing with. The robot's body isn't draw in this representation as it's not the main focus here. |
| 775 | * The "*wheels*": these are just the `GoPiGo3`_'s wheels - selfexplanatory. |
| 776 | |
| 777 | The effect of this class method is that the `GoPiGo3`_ will rotate in the same spot (depending on ``degrees`` parameter), while the wheels will be describing a perfect circle. |
| 778 | |
| 779 | So, in order to calculate how much the motors have to spin, we divide the *angle* (at which we want to rotate the robot) by 360 degrees and we get a float number between 0 and 1 (think of it as a percentage). |
| 780 | We then multiply this value with the *wheel circle circumference* (which is the circumference of the circle the robot's wheels describe when rotating in the same place). |
| 781 | |
| 782 | |
| 783 | At the end we get the distance each wheel has to travel in order to rotate the robot by ``degrees`` degrees. |
| 784 | |
| 785 | """ |
| 786 | # this is the method to use if you want the robot to turn 90 degrees |
| 787 | # or any other amount. This method is based on robot orientation |
| 788 | # and not wheel rotation |
| 789 | # the distance in mm that each wheel needs to travel |
| 790 | WheelTravelDistance = ((self.WHEEL_BASE_CIRCUMFERENCE * degrees) / 360) |
| 791 | |
| 792 | # the number of degrees each wheel needs to turn |
| 793 | WheelTurnDegrees = ((WheelTravelDistance / self.WHEEL_CIRCUMFERENCE) * |
| 794 | 360) |
| 795 | |
| 796 | # get the starting position of each motor |
| 797 | StartPositionLeft = self.get_motor_encoder(self.MOTOR_LEFT) |
| 798 | StartPositionRight = self.get_motor_encoder(self.MOTOR_RIGHT) |
| 799 | |
| 800 | # Set each motor target |
| 801 | self.set_motor_position(self.MOTOR_LEFT, |
| 802 | (StartPositionLeft + WheelTurnDegrees)) |
| 803 | self.set_motor_position(self.MOTOR_RIGHT, |
| 804 | (StartPositionRight - WheelTurnDegrees)) |
| 805 | |
| 806 | if blocking: |
| 807 | while self.target_reached( |
| 808 | StartPositionLeft + WheelTurnDegrees, |
| 809 | StartPositionRight - WheelTurnDegrees) is False: |
| 810 | time.sleep(0.1) |
| 811 |
no test coverage detected