Line 70: | Line 70: | ||
==Classes are Data-types== | ===Classes are Data-types=== | ||
We can use our „Motor“ - class the same way we are using other data - types (int, long, float). | We can use our „Motor“ - class the same way we are using other data - types (int, long, float). | ||
Line 79: | Line 79: | ||
Motor rightMotor; // declare another object of the type „Motor“ called „rightMotor“ | Motor rightMotor; // declare another object of the type „Motor“ called „rightMotor“ | ||
'' | '' | ||
==Calling inner functions of a class (Methods)== | ==Calling inner functions of a class (Methods)== |
Revision as of 10:51, 28 March 2017
Motivation
Soon after starting to write the program for your robot you will encounter some typical problems:
- clarity: the bigger the program gets the harder it is to keep the general overview
- decoupling: you only want to change a certain part of the program without influencing all the rest
- recyclability: there are several similar parts in your robot for which you would like to reuse particular sections of your code
These problems reach back to the beginning of programming and their solution is an art and a science at the same time.
It generally helps a lot to separate your program into single subunits that are relatively independent from each other.
Example: Controlling Motors
The function is an enormous useful tool that can help you structuring your code. Functions allow you to sum up several operations under the same command. This command can be called again and again without knowing about or duplicating the included code.
Here is an example for a function for setting the speed of a motor that is connected to an H-bridge:
void setMotorSpeed(int newSpeed, int forwardPin, int reversePin, int throttlePin){
// should it spin forwards or backwards?
if(newSpeed>0){
//spin forwards
digitalWrite(reversePin,LOW);
digitalWrite(forwardPin,HIGH);
}else{
//spin backwards
digitalWrite(forwardPin,LOW);
digitalWrite(reversePin,HIGH);
}
//adjust the speed:
analogWrite(throttlePin, newSpeed);
}
Now (and for every prospective motor movement) we only need to write one single line in order to for instance setting the left wheels speed:
setMotorSpeed(speed, leftForwardPin, leftReversePin, leftThrottlePin); // the pin numbers are saved in variables
This already saves us a lot of typing –
But one thing still seems quite laborious: we have to know the exact pin numbers every time we want to change the speed.
Imagine a program in which similar function calls are distributed all over. In case of a hardware update you would have to find every single function call and change the parameters manually. This effort could surely be spent for more useful things..
It would be ideal to find a way of calling a certain function that only offers the most useful parameters (like setting the speed) and which handles technical details (switching pins on and off) internally.
Possible solution: Data and code in one package „Classes“ and „Objects“
C++ (and also Arduino) provides a specific feature that can solve our problem: Classes and Objects
A Class predefines common qualities of a group of Objects. It for instance determines that every motor has the possibility to exert a certain amount of throttle. The corresponding program could look like this:
class Motor{
public: // the following qualities and methods are visible from the outside.
void setThrottle(int newThrottle); // every motor has the possibility to exert trottle.
}
Now the computer knows that there is a class called „Motor“.
This class (class) provides a function called „setThrottle“ that is called as an argument by using a number (int) and that does not return anything (void).
Classes are Data-types
We can use our „Motor“ - class the same way we are using other data - types (int, long, float). The following lines use that quality in order to implement two motors:
Motor leftMotor; // declare an object of the type „Motor“ called „leftMotor“
Motor rightMotor; // declare another object of the type „Motor“ called „rightMotor“
Calling inner functions of a class (Methods)
Imagine we want to drive the left motor with full throttle whereas the right motor should stop completely. This can be expressed as follows:
// the objetcs name „leftMotor“ and the herein implemented function „setThrottle“ are separated by a dot.
leftMotor.setThrottle(255);
rightMotor.setThrottle(0);
A positive side effect: your program gains readability by picking distinct names for your Objects and Methods.