0

Line Robot - Basic lessons - Program flow

Let's call a task our robot must complete an "action". Examples of actions are:
  • follow wall,
  • follow line,
  • catch a ball.
A common implementation (the way we write code) of an action will be a function. Doing so, we can call the function (and start) the action using Bluetooth terminal. We know this already: typing "loo" will start loop() and start the action coded in this function. So, we can start the action using a mobile phone, but that is not enough. We have to have a way to start it in our program. Suppose that You want to change 2 actions: first You follow a line, then in certain circumstances follow a wall, then possibly again a line, etc. How to solve this very common task? Search mrm-robot-line.cpp and find these 2 functions:
...
void RobotLine::lineFollow() {
	...
}
...
void RobotLine::wallFollow() {
	...
}
Let's also assume that You changed the content of these 2 functions so that they do what the name suggests: "lineFollow()" will perform line following and wallFollow() wall following. Now back to our problem: how to make the whole program that will execute them alternately. You first naive idea might be:
...
void RobotLine::lineFollow() {
	...
	wallFollow();
	...
}
...
void RobotLine::wallFollow() {
	...
	lineFollow();
	...
}
So, while following a line, when it is appropriate moment, You will call (start) function "wallFollow()" and the robot will start following the wall. That will work. Later, in the "wallFollow()" You decide to start following the wall and call "lineFollow()". So far, so good, but notice a subtle problem: You are getting deeper and deeper in nested calls. Maybe You do not understand this problem now, but You should accept that this is not good at all and it will not be possible to return where You started. You cannot combine actions in this way. All right, we will do it the right way now:
...
void RobotLine::lineFollow() {
	...
	actionSet(actionWallFollow);
	...
}
...
void RobotLine::wallFollow() {
	...
	actionSet(actionLineFollow);
	...
}
There are 2 new commands here. We used the command "end()" already, which ends current action (its function). The command "actionSet()", introduced here, doesn't end the program, but changes the action to a new one. So, the program line:
actionSet(actionWallFollow);
ends "lineFollow()", but also starts action "actionWallFollow", which starts its function "wallFollow()", and happy-end: the program execution jumped from "lineFollow()" to "wallFollow()". You can safely jump back with
"actionSet(actionLineFollow);"
and "lineFollow()" will continue executing again. As any action can have its menu entry, "actionLineFollow" has one: "lin". You can start the program entering "lin" in Your terminal.

Task: change executing functions.

Write a program that will first start executing function "wallFollow()", then immediately jump to "lineFollow()", then and. "wallFollow()" can be started with terminal shortcut "wal".