I'm trying to make a internal coordinate system for an EV3 Python project I'm doing, but at a complete loss on how to do it. It needs to keep track of how it moves (with wheels) in an X, Y coordinate system. The space that the project operates in will only have the robot move in mainly X and Y directions.
1 Answer
What you're trying to accomplish is called Odometry, and fortunately it's a pretty common task in robotics so there's a lot of information available on how to do it. The short answer is, it's relatively easy to implement, but hard to make it work really well.
Let's make things simpler by deciding that the robot can only a) drive straight and b) turn 90 degrees. In other words, the robot reaches an x,y coordinate only by driving along the cardinal directions N, S, E, W. We can make this simplification to avoid having to use trigonometry.
Now we need some variables to keep track of a) where the robot is, and b) what direction it's facing.
Make a variable "orientation" to remember which direction the robot is facing. 1=N, 2=E, 3=S, 4=W, for example.
Make variables "X" and "Y" to remember the position. These can represent whatever units of length you want. Let's just say X and Y represent motor rotations, for simplicity.
When the robot moves straight, you should update the coordinates X or Y depending on which direction it is facing. For example, if the robot drives 3 rotations fwd:
- If orientation==1 (North), increase Y by 3 (rotations).
- If orientation==2 (East), increase X by 3
- If orientation==3 (South), decrease Y by 3
- If orientation==4 (West), decrease Y by 3.
When the robot turns 90 degrees, you should update the orientation variable accordingly. See my other post for how to rotate your robot a specific number of degrees. Assuming a clockwise rotation,
- If orientation==1 (North), set orientation==2 (East).
- If orientation==2 (East), set orientation==3 (South).
- If orientation==3 (South), set orientation==4 (West).
- If orientation==4 (West), set orientation==1 (North).
Assuming you always update your coordinates and orientation whenever you move, your robot should be able to (roughly) keep track of its position using this method. You can make it easier for yourself by putting the DriveStraight and Turn90 code into functions (MyBlocks, if you're using the standard Lego software). For example, the DriveStraight function/MyBlock should take the desired number of rotations, drive the robot that far, and update the global X/Y variables. Similar for Turn90. Then your entire program consists of DriveStraight and Turn90 blocks to move around, and at any time you can read the X,Y coordinate and orientation from your global variables.
One problem with this method is that for every movement your robot makes, error accumulates, until eventually its internal position is no longer accurate. The easiest way to account for this is to occasionally return to a known physical location - for example, a wall corner at 0,0 - and reset X,Y to 0,0 when it gets there. A lot of FLL robots use this technique - these robots have square edges and back themselves into corners to force themselves into a known absolute position/orientation.