MRMS
mrm-robot-maze.h
1 #pragma once
2 #include <mrm-action.h>
3 #include <mrm-robot.h>
4 
5 enum Direction{UP, LEFT, DOWN, RIGHT, NOWHERE};
6 enum LedSign { MAZE_IMU_FOLLOW, MAZE_LED_PAUSE, MAZE_LED_PLAY, MAZE_WALL_DOWN_FOLLOW, MAZE_WALL_LEFT_FOLLOW, MAZE_WALL_RIGHT_FOLLOW, MAZE_WALL_UP_FOLLOW }; // For mrm-8x8 display.
7 enum WallStatus{ NO_WALL, WALL_UNKNOWN, WALL_WITH_VICTIM, WALL_WITHOUT_VICTIM};
8 enum TileSurvace{ SURFACE_BLACK, SURFACE_SILVER, SURFACE_UNKNOWN, SURFACE_WHITE};
9 
10 
13 class Tile {
14 
15  uint8_t _wall; // 1 byte stores statuses for all 2 walls enclosing the tile. Bit 7:6 - right, 5:4 - down, 3:2 - left, 1:0 - up.
16  uint8_t _surface; // 1 byte stores surface and other data. Bit 7:6 - surface. The rest 6 bytes can be freely used. This feature is not in use yet.
17  Tile* _chain; // Pointer to the next tile in chain.
18 
19 public:
20  static Tile* first; // Static member variable (one instance for the whole class), pointing to the first tile of the chain.
21 
22  Direction breadcrumb; // Stores direction of the previous tile, needed for Tremaux algorithm. This sequence is independent of the one made by _chain variable, which is only used for traversing the chain.
23  int8_t x; // x coordinate of the tile. Increasing in RIGHT direction.
24  int8_t y; // y coordinate of the tile. Increasing in UP direction.
25 
31  Tile(int8_t x, int8_t y, Direction breadcrumb);
32 
36  Tile* next() { return _chain; }
37 
42  WallStatus wallGet(Direction direction) { return (WallStatus)((_wall >> (direction * 2)) & 0b11); }
43 
48  void wallSet(Direction direction, WallStatus wallStatus) { _wall &= ~(0b11 << (direction * 2)); _wall |= (wallStatus << (direction * 2)); }
49 };
50 
51 
52 /* All the Action-classes have to be forward declared here (before RobotMaze) as RobotMaze declaration uses them. The other option would be
53 not to declare them here, but in that case Action-objects in RobotMaze will have to be declared as ActionBase class, forcing downcast later in code, if
54 derived functions are used.*/
55 class ActionDecide;
56 class ActionMap;
57 class ActionMove;
58 class ActionMoveAhead;
59 class ActionMoveTurn;
60 class ActionRescueMaze;
61 class ActionWallsTest;
62 
65 class RobotMaze : public Robot {
66  // Change these values to get optimal robot's behaviour.
67  const uint16_t IMU_FOLLOW_STRENGTH = 5; // A bigger value increases feedback.
68  const uint16_t MAZE_MAX_STEPS = 0xFFFF; // Can be used to stop the robot after a certain number of steps, for example for debugging purpose.
69  const uint16_t MOVE_AHEAD_TIMEOUT_MS = 1300; // If no encoders available, the robot will stop after this time elapses, when moving ahead over 1 tile.
70  const uint16_t NO_WALL_DISTANCE = 250; // In mm. When a sensor measures a value bigger than this one, it will declare there is no wall in front of it.
71  const uint8_t TOP_SPEED = 127; // Can be used to slow down the robot. Maximum value is 127. Enter 0 to test the robot without motors working.
72  const uint16_t WALL_FOLLOW_DISTANCE = 90; // Distance for wall following. Normally it should be (300 mm - 120 mm) / 2. 300 mm is tile's width and 120 mm is robot's width.
73  const uint16_t WALL_FOLLOW_ERROR_ALLOWED = 40; // In mm. If 2 sensors measure distances that diverge in values more than this number, the robot will not follow that wall.
74  const uint16_t WALL_FOLLOW_DISTANCE_ADJUSTMENT_STRENGTH = 1.1; // A bigger value will force the robot to correct distance to a wall more vigorously.
75  const uint16_t WALL_FOLLOW_ROTATION_STRENGTH = 1.1; // A bigger value will force the robot to correct its alignment to a wall more vigorously.
76 
77  // Actions' declarations
78  ActionDecide* actionDecide;
79  ActionBase* actionGoStraightAhead;
80  ActionMap* actionMap;
81  ActionMove* actionMove;
82  ActionMoveAhead* actionMoveAhead;
83  ActionMoveTurn* actionMoveTurn;
84  ActionRescueMaze* actionRescueMaze;
85  ActionWallsTest* actionWallsTest;
86 
87  Direction directionCurrent; // Current robot's direction.
88 
89  float imuLastValid = 9999; // Last measured compass value. Important for moving ahead when no wall available.
90 
91  MotorGroupDifferential* motorGroup = NULL; // Class that conveys commands to motors.
92 
93  uint16_t stepCount; // Number of steps made.
94 
95  Tile* tileCurrent; // Current tile (robot's position).
96 
97 public:
101  RobotMaze(char name[] = (char*)"RCJ Maze");
102 
105  void bitmapsSet();
106 
109  void decide();
110 
118  uint16_t distance(Direction direction, bool firstCCW) {return mrm_lid_can_b->reading(2 * mToR(direction) + firstCCW); }
119 
123  void directionDisplay(Direction direction);
124 
127  void goAhead() {}
128 
131  void imuFollow();
132 
135  void loop();
136 
139  void map();
140 
143  void mazePrint();
144 
147  void move();
148 
151  void moveAhead();
152 
155  void moveTurn();
156 
157  /* Direction from maze's perspective to robot's perspective. Robot's front is TOP, robot's back is DOWN.
158  @param directionAsSeenInMaze - direction from maze's prespective.
159  @return direction from robot's perspective.
160  */
161  Direction mToR(Direction directionAsSeenInMaze) { int8_t d = directionAsSeenInMaze - directionCurrent; return (Direction) (d < 0 ? d + 4 : d); }
162 
165  void omniWheelsTest();
166 
169  void rescueMaze();
170 
171  /* Direction from robot's perspective to maze's perspective. Robot's front is TOP, robot's back is BACK.
172  @param directionAsSeenByRobot - direction from robot's perspective.
173  @return direction from maze's perspective.
174  */
175  Direction rToM(Direction directionAsSeenByRobot) { return (Direction)(directionCurrent + directionAsSeenByRobot % 4); }
176 
182  Tile* tileContaining(int8_t x, int8_t y);
183 
187  Direction wallClosest();
188 
192  void wallFollow(Direction wallDirection);
193 
196  void wallsDisplay();
197 
204  WallStatus wallGet(int8_t x, int8_t y, Direction direction);
205 
210  void wallDisplay(WallStatus wallStatus, Direction direction);
211 
214  void wallsTest();
215 
220  int8_t x(Direction direction);
221 
226  int8_t y(Direction direction);
227 };
228 
229 
254 class ActionDecide : public ActionBase {
255  void perform() { ((RobotMaze*)_robot)->decide(); }
256 public:
257  ActionDecide(Robot* robot) : ActionBase(robot, "", "") {}
258 };
259 
262 class ActionMap : public ActionBase {
263  void perform() { ((RobotMaze*)_robot)->map(); }
264 public:
265  ActionMap(Robot* robot) : ActionBase(robot, "", "") {}
266 };
267 
270 class ActionMove : public ActionBase {
271  void perform() { ((RobotMaze*)_robot)->move(); }
272 public:
273  Direction direction; // Initial direction is stored to be recalled when using the action.
274  uint32_t startMs; // Time is stored, for example to be used to determine if the movement's timeout elapsed.
275  ActionMove(Robot* robot) : ActionBase(robot, "", "") {}
276 };
277 
280 class ActionMoveAhead : public ActionMove {
281  void perform() { ((RobotMaze*)_robot)->moveAhead(); }
282 public:
283  ActionMoveAhead(Robot* robot) : ActionMove(robot) {}
284 };
285 
288 class ActionMoveTurn : public ActionMove {
289  void perform() { ((RobotMaze*)_robot)->moveTurn(); }
290 public:
291  float endAngle; // End condition: target angle.
292  float turnByCCW; // Number of degrees to turn CCW (counter-clockwise).
293  ActionMoveTurn(Robot* robot) : ActionMove(robot) {}
294 };
295 
298 class ActionRescueMaze : public ActionBase {
299  void perform() { ((RobotMaze*)_robot)->rescueMaze(); }
300 public:
301  ActionRescueMaze(Robot* robot) : ActionBase(robot, "maz", "Rescue Maze", 1) {}
302 };
303 
307  void perform() { ((RobotMaze*)_robot)->omniWheelsTest(); }
308 public:
309  ActionOmniWheelsTest(Robot* robot) : ActionBase(robot, "omn", "Test omni wheels", 1) {}
310 };
311 
314 class ActionWallsTest : public ActionBase {
315  void perform() { ((RobotMaze*)_robot)->wallsTest(); }
316 public:
317  ActionWallsTest(Robot* robot) : ActionBase(robot, "wlt", "Walls test", 1) {}
318 };
Definition: mrm-action.h:7
ActionBase(Robot *robot, const char shortcut[4], const char text[20], uint8_t menuLevel=1, BoardId boardsId=ID_ANY)
Definition: mrm-action.cpp:23
Definition: mrm-robot-maze.h:254
Definition: mrm-robot-maze.h:262
Definition: mrm-robot-maze.h:280
Definition: mrm-robot-maze.h:270
Definition: mrm-robot-maze.h:288
Definition: mrm-robot-maze.h:306
Definition: mrm-robot-maze.h:298
Definition: mrm-robot-maze.h:314
Definition: mrm-board.h:403
uint16_t reading(uint8_t deviceNumber=0)
Definition: mrm-lid-can-b.cpp:157
Definition: mrm-robot.h:42
Definition: mrm-robot-maze.h:65
void wallFollow(Direction wallDirection)
Definition: mrm-robot-maze.cpp:510
void omniWheelsTest()
Definition: mrm-robot-maze.cpp:407
void move()
Definition: mrm-robot-maze.cpp:309
void map()
Definition: mrm-robot-maze.cpp:235
int8_t y(Direction direction)
Definition: mrm-robot-maze.cpp:676
WallStatus wallGet(int8_t x, int8_t y, Direction direction)
Definition: mrm-robot-maze.cpp:556
int8_t x(Direction direction)
Definition: mrm-robot-maze.cpp:662
void decide()
Definition: mrm-robot-maze.cpp:145
void mazePrint()
Definition: mrm-robot-maze.cpp:256
void rescueMaze()
Definition: mrm-robot-maze.cpp:455
void loop()
Definition: mrm-robot-maze.cpp:222
uint16_t distance(Direction direction, bool firstCCW)
Definition: mrm-robot-maze.h:118
RobotMaze(char name[]=(char *)"RCJ Maze")
Definition: mrm-robot-maze.cpp:16
void directionDisplay(Direction direction)
Definition: mrm-robot-maze.cpp:191
void wallDisplay(WallStatus wallStatus, Direction direction)
Definition: mrm-robot-maze.cpp:567
void wallsDisplay()
Definition: mrm-robot-maze.cpp:595
Direction wallClosest()
Definition: mrm-robot-maze.cpp:487
void bitmapsSet()
Definition: mrm-robot-maze.cpp:54
void goAhead()
Definition: mrm-robot-maze.h:127
void moveAhead()
Definition: mrm-robot-maze.cpp:336
void moveTurn()
Definition: mrm-robot-maze.cpp:380
void imuFollow()
Definition: mrm-robot-maze.cpp:213
void wallsTest()
Definition: mrm-robot-maze.cpp:638
Tile * tileContaining(int8_t x, int8_t y)
Definition: mrm-robot-maze.cpp:477
Definition: mrm-robot-maze.h:13
WallStatus wallGet(Direction direction)
Definition: mrm-robot-maze.h:42
Tile * next()
Definition: mrm-robot-maze.h:36
void wallSet(Direction direction, WallStatus wallStatus)
Definition: mrm-robot-maze.h:48
Tile(int8_t x, int8_t y, Direction breadcrumb)
Definition: mrm-robot-maze.cpp:691