You have to take a look in the behaviour tree description on page 6: BHT Mowing.
Without this description you are not able to do anything.
Each leaf represents a class. Hatched leafs are used again and are defined in another part of the tree.
When I want to find a class, I search for it in the whole project. Classnames begin with T.
All BHT classes are instantiated in behaviour.cpp at the beginning. The BHT is build up in void TBehaviour::setup(). You are not really able to understand this build of the tree without the BHT description.
Another important thing in behaviour.cpp is the function void TBehaviour::reset(). Here all variables of the black board will be initiated.
Implemeting the bumper behaviour:
The Bumperservice has to provide two more funktions: isBumperActivatedLeft() and isBumperActivatedRight() and isBumperActivated() should be extended with _bumperLeftActivated and _bumperRightActivated
Now on the the BHT description you see in the upper left corner the Sequence: mseqBumperActive. This sequence is reponsible to stop the motors, free the bumper and select an escape algortihm. This is a memory sequence. When the next tick is running the node which returned running will be called direct again without calling the nodes on the left side of the running node.
There you can see, that TConBumperActive is the first leaf in the sequence. If this condition is true, the sequence is entered. In TConBumperActive bb.bumperSensor.isBumperActivated() is called to check if the bumper is activated. After the
motor stopped, TFreeBumper is used to free the bumper. That means, the bumper will be freed in the opposit direction the mower has driven. Also the flags flagBumperOutsidePerActivated and flagBumperInsidePerActivated are set. After freeing the bumper, TselEscapeAlgorithm is called. Here the escape algorithm is selected depening on the driven direction and if the perimeter state changed from inside to outside after freeing. For drive direction DD_FORWARD you can see, that the algorithm bb.flagEscabeObstacleConFlag = FEO_ROT; is used if the bumper is activated inside perimeter.
On the right sode of the tree you see the decorator: TdnBumperActivated. Because flagBumperInsidePerActivated is set to true, the branch will be executed. Here the sequence mseqEscBackward is entered because the condition conFEO_ROT is true. (Classs: TconFEO_ROT I forgot somtimed to write the T in the BHT overview). And then you see TSetArcFEO_ROT is called, which sets the parameter for the rotation routine. Here I used a random number to calculate the rotation direction. Here you can also call bb.bumperSensor.isBumperActivatedLeft() and bb.bumperSensor.isBumperActivatedRight() to determine the rotate direction.
If the bumper outside is activated, then flagBumperOutsidePerActivated is true and the brach dnBumpPeriActivated on the right side of the sheet is used. Here the normal perimeter rotation algorithm is used. If you want to change this behaviour here, you could throw out the leaf TCalcAngle and put in TSetArcFEO_ROT. But you have to adapt TselEscapeAlgorithm also.
You have to change:
mseqEscOOPReverse.addChildren(&conFEO_BACKINSIDE, &calcAngle, &mseqRotatePer);
to
mseqEscOOPReverse.addChildren(&conFEO_BACKINSIDE, &setArcFEO_ROT, &mseqRotatePer);
And then test it.
I hope that helps for the first time.
DHT22 Sensor:
You can do this that way, but than you destroy the concept of the code because the hardware should only be called through the hardware.h interface. Therefor we have to create a new in out interface, which is able to change the port direction.
Anyway this can be adapted later. It would be nice if you would create a fork on github for this, than I can adapt this in the code later. Because I want to use this also.
I would realize this as DHT service which is not enabled and not inserted in the controller.
Easiest way is to copy DHT.h and DHT.cpp in he project. Derivate it from the thread class. (I use the
arduino thread library a little bit adapted to my needs)
For this take a look how I have done this in the bumper class.
class TDHT : public Thread{
...
void setup();
//this is you begin- rename it only
virtual void run(); // this must be inserted also
...
{
// implemetn the run function
void TDHT::run()
{
runned();
}
In Raindancer.ino you have then create an instance of the object. Check out how I have done this with the bumper class.
TDHT DHT;
DHT.setup();
DHT.enable=false;
You don't have to put it to the controller, because we don't need calling run at the moment.
You can test it in the loop() function.
As long as you don't call the BHT you can put in as testcode after the loop statement for testing.
Use
errorHandler.setInfo(F("temp: %drn", value)); to print out values.
If this works, the service is finished an now you have to insert it in the BHT - after deleting the test code.
First create a reference for the TDHT Classs in Blackboard class. Blackboard.h. Check out how I did it with the TbumperSensor.
Then you have to change the following constructor to initialize the variable:
Blackboard(TMotorInterface &_motor, TPerimeterThread &_perimeterSenoren, TMowMotorSensor& _mowMotorSensor, TrangeSensor &_rangeSensor,
TbumperSensor &_bumperSensor, TbatterieSensor& _batterieSensor, CRotaryEncoder &_encoderL, CRotaryEncoder &_encoderR, TchargeSystem &_chargeSystem, TEEPROM &_eeprom):
motor(_motor),
perimeterSensoren(_perimeterSenoren),
rangeSensor(_rangeSensor),
bumperSensor(_bumperSensor),
mowMotorSensor(_mowMotorSensor),
batterieSensor(_batterieSensor),
encoderL(_encoderL),
encoderR(_encoderR),
chargeSystem(_chargeSystem),
eeprom(_eeprom)
...
Then in Raindancer.ino you have to change the call of
Blackboard myBlackboard(
motor, perimeterSensoren, mowMotorSensor, rangeSensor, bumperSensor, batterieSensor, encoderL, encoderR, chargeSystem, eeprom);
Now you can access the service form the BHT over the blackboard.
For this I would create a new leaf in the tree and put it direct after TOverRun in mseqPerimeterForward. Because here the mower has stopped.
For creating the leafe I would copy the class TOverRun and rename it.
How to insert it in behaviour.cpp check out how I did it with TOverRun. And insert it in mseqPerimeterForward after &TOverRun .
Good luck