Robot joints come in two basic kinds. A revolute joint turns: its value is an angle. A prismatic joint slides: its value is a distance, like a telescope pulled out. A fruit-picking arm combines both: a turning shoulder, a telescoping boom, a turning wrist.
The arm is planar, its base at the origin, pointing along +x before the first part. x points right and y up; angles are in radians, counter-clockwise. From base to hand, the arm is a list parts; each part is one of:
("R", angle, length): a revolute joint that turns the current direction byangle(relative to the direction so far), followed by a rigid link oflengthin the new direction;("P", extension): a prismatic joint, a telescoping link that reachesextensionfurther along the current direction, without turning (0means fully retracted).
Write chain_pose(parts) that returns the hand's pose (x, y, heading): the position at the end of the last part, and the current direction there, measured from +x and wrapped into (-\pi, \pi] (whole turns of 2\pi added or subtracted; a direction along -x is \pi, never -\pi).
Examples
Input: parts = [("R", math.pi / 2, 1), ("P", 0.5), ("R", -math.pi / 2, 0.3)]
Output: (0.3, 1.5, 0.0)
Explanation: the shoulder points the first link up to (0, 1); the boom slides
0.5 further up, to (0, 1.5); the wrist turns back to +x and adds 0.3.
Input: parts = [("P", 2), ("R", math.pi / 2, 1), ("P", 0)]
Output: (2.0, 1.0, 1.57079633)
Explanation: a rail first carries the arm 2 along +x.
Input: parts = [("R", 3.0, 0.5), ("P", 0.25), ("R", 2.0, 0.4)]
Output: (-0.6290295, -0.2777297, -1.28318531)
Explanation: the turns add up to 5.0 radians, which is 5.0 - 2 * pi once wrapped.
Constraints
- answers are compared with a tolerance of
1e-6; do not round
Goals
- Treat a sliding joint as a link whose length is the joint value
- Walk a chain that mixes turning and sliding joints
- Return the hand's heading wrapped into $(-\pi, \pi]$