Da ich die L298N Motortreiber verwende, muss in der mower.cpp noch in der Methode readSensor der Aufruf von checkMotorFault auskommentiert werden. Andernfalls gibt es nur Motor Fault Errors

int Mower::readSensor(char type){
  switch (type) {
// motors------------------------------------------------------------------------------------------------
    case SEN_MOTOR_MOW: return ADCMan.read(pinMotorMowSense); break;
    case SEN_MOTOR_RIGHT: //checkMotorFault(); 
              return ADCMan.read(pinMotorRightSense); break;
    case SEN_MOTOR_LEFT: // checkMotorFault(); 
              return ADCMan.read(pinMotorLeftSense); break;
    //case SEN_MOTOR_MOW_RPM: break; // not used - rpm is upated via interrupt

Wenn der Mower im manuellen Modus irgendwo gegen fährt, schiebt er im original Code einfach weiter. Durch die Anpassung weiter oben bleibt er zumindest stehen. Da er aber nicht zurück setzt, bleibt der Bumper ewig aktiv und man bekommt den Mower nur von Hand raus. Normalerweise fährt der Mower ja zurück und dreht dann, ich will, dass er nur zurück setzt und dann stehen bleibt. Dazu sind einige Anpassungen erforderlich gewesen:

1. robot.h: Hier wird dem ENUM für die roll types ein weiterer Wert (NONE) eingefügt

// roll types
enum { LEFT, RIGHT, NONE };

2. robot.cpp
Zunächst ändern wir das Verhalten vom STATE_MANUAL. Wenn ein Bumper aktiviert wurde, wird nun reverseOrBidir(NONE) aufgerufen

case STATE_MANUAL:
      if ((bumperLeft || bumperRight)) {    
         reverseOrBidir(NONE);
      }
      break;

Die Methode reverseOrBidir bleibt wie gehabt. Die Methode setzt als nächsten State STATE_REVERSE (sofern kein bidirektionales Mähen). Diesen State müssen wir anpassen.

      if (mowPatternCurr == MOW_BIDIR){
        double ratio = motorBiDirSpeedRatio1;
        if (stateTime > 4000) ratio = motorBiDirSpeedRatio2;
        if (rollDir == RIGHT) motorRightSpeedRpmSet = ((double)motorLeftSpeedRpmSet) * ratio;
          else motorLeftSpeedRpmSet = ((double)motorRightSpeedRpmSet) * ratio;                                
        if (stateTime > motorForwTimeMax){ 
          // timeout 
          if (rollDir == RIGHT) setNextState(STATE_FORWARD, LEFT); // toggle roll dir
            else setNextState(STATE_FORWARD, RIGHT);
        }        
      } else {        
        if (millis() >= stateEndTime) {
          if (rollDir != NONE) {
              setNextState(STATE_ROLL, rollDir);				                         
          }
          else { 
            setNextState(STATE_MANUAL, 0);
          }
        }
      }
      break;
    case STATE_PERI_ROLL:

Hier wurde eine weitere Prüfung auf rollDir eingefügt. Wenn dieser den Wert NONE hat, befinden wir uns im manuellen Modus und sind irgendwo dran gekommen. Somit ist der neue State STATE_MANUAL und nicht wie bisher STATE_ROLL.

In der Methode setNextState wird nun geprüft, ob der alte Status STATE_REVERSE und der neue STATE_MANUAL ist (ziemlich am Ende).

  if (stateNew == STATE_PERI_TRACK){        
    //motorMowEnable = false;     // FIXME: should be an option?
    setActuator(ACT_CHGRELAY, 0);
    perimeterPID.reset();
    //beep(6);
  } 

    // Reverse im manuellen Modus, im Manuellen Modus wurde der Bumper ausgelöst
  if (stateNew == STATE_MANUAL && stateCurr == STATE_REVERSE)
  {
    motorLeftSpeedRpmSet = motorRightSpeedRpmSet = 0;
  }
  
  if (stateNew != STATE_REMOTE){
    motorMowSpeedPWMSet = motorMowSpeedMaxPwm;
  }

Somit wird erreicht, dass der Mower nach dem zurück setzen auch wieder stehen bleibt. Andernfalls würde er ewig zurück setzen.