A Move object can be used to describe a move made by a vehicle, or a move you want the vehicle to make. In natural English, we describe both of these moves using the same language:
Describing move to make: Q: How do I get to the gas station? A: Forward two miles, right 90 degrees, forward 6 miles.
Describing a move you just made: Q: How did you get here from the farm? A: Forward two miles, right 90 degrees, forward 6 miles.
In our API, a Move can describe to the Deadreckoner the distance and angle changes a vehicle made. In our API, a Move can also describe a move the MoveController should make. There does not seem to be any reason why our API would need to use two different classes to represent moves.
- A move increment is represented by change in distance, change in angle, and (optionally if we want velocity control/reporting) change in time.
- Move should be a collection of move increments.
- This Move collection could contain only one move, or multiple, just like any other collection.
- The same Move object should be used for recording a move as instigating a queue of moves.
- The incremental spacing should be variable, controlled by the class using it. (also allows regular spaced increments)
- This Move object is the "virtual line" that our Move-Control-Feedback could follow.
Examples of Move Uses
Creating a Move queue to execute
|#||angle (deg)||dist (cm)||T (sec)|
Reporting a Straight Line
The diagram below shows four different versions of the same move:
- The Requested move is 15 cm with no rotation (a straight line)
- When the vehicle actually moves, it inadvertently rotates -5 degrees at the start when one wheel rotates more than the other, and when it stops it rotates +5 degrees.
- The current "single move" system records this as an average over the course of the move, so it incorrectly believes the robot moves to the solid dot, when in fact it moved to the white dot.
- The proposed Move class can more accurately report that at the start of the move it rotated, and at the end of the move it rotated, resulting in a more accurate estimation of the move.
Reporting an Arc
One of the advantages to using one common data class to represent a Move is that we could have additional Move methods that fuse/transform Move increments, similar to how String methods transform and compare characters.
- Move.submove(start, end);
- boolean Move.equal(Move)
- boolean Move.isLonger(Move) // longer distance
- boolean Move.takesLonger(Move) // longer time
This is a much more simple and robust tool set for users compared to having two separate and different classes to represent moves made and moves to make.
The advantage of using one common object to describe a path is that it can be used to draw the path it intends to take (before it executes it) and then overlay the path it actually took. This will be easier if we use one common object:
Requesting a Move
// Construct a Move (normally PathPlanner or PoseController do this) Move move = new Move(); move.addSegment((angle, distance, time); // Ask MoveController to execute move moveController.move(move);
// A move is reported from MoveProvider Move move = deadreckoningMoveProvider.getMove(); // Reverse the Move: Move moveBack = move.reverseMove(); // Now drive back to starting point: moveController.move(move); // Append another move: move.append(moveBack); // Now make vehicle perform mirrored move moveController.move(move);