RobotMath: Angular Arithmetic
From Tekkotsu Wiki
Contents |
Measuring Angles
Angles are used in robotics to represent the robot's heading, the relative bearings of landmarks, and the positions of the robot's joints. In this lesson you will learn how to do arithmetic with angles, convert between degrees and radians, and do angular computations in C++.
In everyday life we measure angles in degrees, with 360 degrees to a circle. Compasses used by sailors, pilots, and hikers measure angles with respect to magnetic North, represented as zero degrees, or equivalently, 360 degrees. 90 degrees is East, 180 degrees is South, and 270 degrees is West. The markings on compasses are frequently in tens of degrees, as in the aircraft gyrocompass at left, so "3" denotes 30 degrees, or North-Northeast. On the hiker's compass at right the markings are in whole degrees.
Headings (angles relative to North) increase in the clockwise direction on a compass, so Northeast (heading 45 degrees) is to the right of North. But in mathematics textbooks angles are measured as displacements from the positive x axis toward the positive y axis, so angular values increase in the counter-clockwise direction, as shown below:
In mathematics textbooks, the positive x axis points to the right and the positive y axis points up. | In robotics, the positive x axis points forward and the positive y axis points to the left. |
Tekkotsu follows the convention used for describing the kinematic structure of robots: the x axis points forward, ahead of the robot, and the y axis points to the left. The z axis points up, so when the robot turns, it is rotating about its z axis. Following the right hand rule from physics, with the x axis pointing forward and the z axis pointing up, the y axis must point to the left. So angles increase in the counter-clockwise direction, the same as in a math textbook, but the opposite of a pilot's compass.
In engineering applications, and in most computer languages, angles are expressed in radians instead of degrees. A radian is the angle subtended by an arc along a circle whose length is equal to the circle's radius. A full circle is therefore 2π radians, making a radian roughly 57°. Using radians instead of degrees makes some kinds of math more elegant. (Some examples, if you're mathematically inclined: in trigonometry, the derivative of the sine function is exactly the cosine function when angles are measured in radians. And in complex arithmetic, if a complex number z is expressed in polar form as (r,θ), then z = re^{iθ} when θ is expressed in radians. If we used degrees in these calculations we would have to multiply everything by a constant term; radians are the "natural" units for measuring angles because then the constant is 1.)
Textbooks may represent angles using either degrees or radians; some use both. Angles in Tekkotsu are always measured in radians. Given the coordinate system Tekkotsu uses, with the positive y axis pointing to the robot's left, a turn value of -0.5, meaning -0.5 radians, would be a roughly 28.6° turn to the right.
Commonly-Used Angles
Since 360° equals 2π radians, we can easily calculate some other common angles:
Degrees | Radians | Radians (Decimal) |
---|---|---|
360° | 2π | 6.28 |
180° | π | 3.14 |
90° | π/2 | 1.57 |
60° | π/3 | 1.05 |
57.296° | 1 | 1.0 |
45° | π/4 | 0.785 |
30° | π/6 | 0.524 |
Questions:
- If you want your robot to make a 90 degree turn to the left, but it only understands radians, what turn amount should you use?
- What value should you use for a 45 degree turn to the right?
- How many radians is 15 degrees?
- How many degrees is π/18 radians? (You should be able to solve this without a calculator; use the table above.)
- A ground-based robot like the Create turns about its z axis. Consider a robotic airplane, which can rotate about any axis. When the robot banks its wings, what axis is it rotating about? When it pitches its nose up to climb, what axis is it rotating about? Is a pitch-up motion a positive or a negative rotation about that axis? (Research the right hand rule to determine this.)
Converting Degrees to Radians
Here's how to remember the formula for converting degrees to radians: you take out the degrees by dividing by 360, and you put in the radians by multiplying by 2π:
Question: How would you convert from radians to degrees?
Angular Arithmetic
Angular arithmetic is circular, e.g., if a robot turns 20 degrees to the left it ends up at the same place as if it had turned 340 degrees to the right. So 20° is the same as -340°. Also, the farthest you can get from 0° is 180° no matter which way you turn, so a turn (or a heading) of -180° is the same as 180°. In radians, -π takes you to the same place as π. And 0 is the same as 2π.
Formally, we say that two angles α and β are of equal value if α = β (modulo 2π).
Questions:
- What angle between 0 and 2π is represented by 7/3 π ?
- What angle between 0 and 2π is represented by -π/18 ?
- Prove that a turn by any angle α is equivalent to a turn in the opposite direction by 2π-α
Angle Computations in Tekkotsu
C++ includes a built-in constant M_PI for the value π. Tekkotsu provides functions deg2rad(degs) and rad2deg(rads) for converting between degrees and radians
Tekkotsu contains two built-in classes for angular arithmetic: AngTwoPi and AngSignPi. AngTwoPi represents angles as values between 0 and 2π, while AngSignPi represents them as values between -π and +π. The standard arithmetic operators +-*/ have been overloaded to work on these classes. Tekkotsu uses AngTwoPi to represent the robot's heading on the world map. AngSignPi is useful for representing turns, with positive values indicating left turns and negative values right turns. Values wrap around appropriately, so converting 4π/3 to an AngSignPi produces -π/3, and converting 3.5π to an AngTwoPi produces 1.5π.
Here is some sample code demonstraing angular arithmetic.
#include "Behaviors/StateMachine.h" $nodeclass AngularMath : StateNode : doStart { AngTwoPi initialHeading = M_PI / 5; AngSignPi turnAmount = deg2rad(-75.); AngTwoPi newHeading = initialHeading + turnAmount; cout << "Initial heading " << rad2deg(initialHeading << " deg. = " << initialHeading << " radians" << endl; cout << "Turn amount " << rad2deg(turnAmount) << " deg. = " << turnAmount << " radians" << endl; cout << "New heading " << rad2deg(newHeading) << " deg. = " << newHeading << " radians" << endl; } REGISTER_BEHAVIOR(AngularMath);
Questions
1. Write code to calculate the sum of 541° and 13π radians and express the result in degrees.
2. Consider the following state machine that causes a robot to back up and then turn left by 37.5° whenever it hits a wall:
startnode: ForwardNode(99999) =PILOT(collisionDetected)=> WalkForward(-50) =C=> Turn(deg2rad(37.5)) =C=> startnode
Assuming the robot starts out with a heading of 0°, write a C++ expression to calculate the robot's heading after it has bumped into something 10 times.
3. What output does the following code produce?
AngTwoPi x = M_PI / 6; AngTwoPi value1 = - x; AngSignPi value2 = value1; cout << value1 << " " << value2 << endl;
4. The AngTwoPi and AngSignPi classes are defined in the files /usr/localTekkotsu/Shared/Measures.h and Measures.cc. What does the AngTwoPi::normalize() method do, and how does it work?
5. Why does deg2rad(75) generate a compiler error but deg2rad(75.0) compile correctly?
Reflection
What were the key points you learned about angular arithmetic?
When people drastically change their opinion on a subject, such as going from hating broccoli to loving broccoli, one may say they have made a "180 degree reversal". If we chose to use radians in common conversation instead of degrees, how might we refer to such a change in opinion?