1.0a4-Azurit

Das gleiche Problem habe ich auch immer noch.
Mit der alten Software ging es noch, zumindest bei den ersten Versuchen im Keller.
 
So as soon as it hits the perimeter, one wheel is going forward, one wheel is going backwards. This is different from what I was having.

what is your Transition timeout in your perimeter settings? By default it is 2000

Frederic
 
First it drives straight to the perimeter. As soon it hits the perimeter, it turns right. But it doesnt stop turning as it crosses the perimeter again (left wheel forward and right wheel backwards). After a few seconds it changes the state and the left wheel goes forward and the right wheel stops (no turning on the position, instead driving in a bigger radius right-curve). After another few seconds it stops with perimeter error.
It is interesting, that the perimeter status is OUTSIDE from the moment, it hits first the perimeter. It seems, that the perimeter-coil is not correctly calculated from this moment.

Greets,
Jem
 
Hi Jem,

When it is looking fot the perimeter, it should indeed turn right. I was thinking one wheel would be stopped in this state, but I was wrong, the code shows that both wheels are running


Code:
} else {
      // we are outside, now roll to get inside
      motorRightSpeedRpmSet = -motorSpeedMaxRpm / 1.5;
      motorLeftSpeedRpmSet  = motorSpeedMaxRpm / 1.5;
    }


Looking at what happens next:


Code:
t    13 l2868 v0 PFND spd   16  -16    0 sen    0    0    0 bum    0    0 dro    0    0 son   0 yaw   0 pit   0 rol   0 per   3 bat 12.4 chg  0.0  0.0 imu  0 adc116 Ardumower

t    14 l2326 v0 PFND spd   16  -16    0 sen    0    0    0 bum    0    0 dro    0    0 son   0 yaw   0 pit   0 rol   0 per   3 bat 12.4 chg  0.0  0.0 imu  0 adc116 Ardumower

t    15 l2203 v0 PFND spd   16  -16    0 sen    0    0    0 bum    0    0 dro    0    0 son   0 yaw   0 pit   0 rol   0 per   3 bat 12.4 chg  0.0  0.0 imu  0 adc116 Ardumower

t     0 l2130 v0 PTRK spd   16  -16    0 sen    0    0    0 bum    0    0 dro    0    0 son   0 yaw   0 pit   0 rol   0 per   4 bat 12.4 chg  0.0  0.0 imu  0 adc 49 Ardumower

t     0 l2130 v0 PTRK spd   16  -16    0 sen    0    0    0 bum    0    0 dro    0    0 son   0 yaw   0 pit   0 rol   0 per   4 bat 12.4 chg  0.0  0.0 imu  0 adc 57 Ardumower

t     1 l2543 v0 PTRK spd   16  -16    0 sen    0    0    0 bum    0    0 dro    0    0 son   0 yaw   0 pit   0 rol   0 per   4 bat 12.4 chg  0.0  0.0 imu  0 adc117 Ardumower


it does see the perimeter again, but it does not change the motor speeds and keeps turning.

If you ask me, this really looks like the issue I fixed. Dut you say you have fixed this in the code yourself?
To be sure, I would like to suggest that you try the develop branch https://github.com/Ardumower/ardumower/tree/develop You will have to reconfigure the mower again and recalibrate because the settings have changed....

Frederic
 
Here is console log of perimeter sensor during HOME.

Logged are 2 tries:
First try everything looked good at first glance. PFND until it reaches the perimeter, then turning during PFND and as soon it has a perimeter transition from outside to inside it changes to PTRK. But now it is a wrong behaviour. The mower turns furthermore and had a perimeter transistion and after 8 more seconds it reaches errorlevel.
Seconds try is completely the same.

I do not know what to do next, as the code looks correct for me ...

Greets,
Jem
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/1536/mower2_1stTry.txt/
 
Zuletzt bearbeitet von einem Moderator:
I have no power.cpp ... :unsure:

I just uploaded a new sketch, where I uncommented the PID-output to the console in robot.cpp at approx. line 860:


Code:
// PID controller: track perimeter 
void Robot::motorControlPerimeter(){    
  if (millis() < nextTimeMotorPerimeterControl) return;
    nextTimeMotorPerimeterControl = millis() + 100;

  if ((millis() > stateStartTime + 5000) && (millis() > perimeterLastTransitionTime + trackingPerimeterTransitionTimeOut)){
    // robot is wheel-spinning while tracking => roll to get ground again
    if (trackingBlockInnerWheelWhilePerimeterStruggling == 0){
    if (perimeterMag < 0) setMotorPWM( -motorSpeedMaxPwm/1.5, motorSpeedMaxPwm/1.5, false);
        else setMotorPWM( motorSpeedMaxPwm/1.5, -motorSpeedMaxPwm/1.5, false);}

    else if (trackingBlockInnerWheelWhilePerimeterStruggling == 1){
      if (perimeterMag < 0) setMotorPWM( 0, motorSpeedMaxPwm/1.5, false);
        else setMotorPWM( motorSpeedMaxPwm/1.5, 0, false);
    }

    if (millis() > perimeterLastTransitionTime + trackingErrorTimeOut){      
      Console.println("Error: tracking error");
      addErrorCounter(ERR_TRACKING);
      //setNextState(STATE_ERROR,0);
      setNextState(STATE_PERI_FIND,0);
    }
    return;
  }   
  if (perimeterMag < 0) perimeterPID.x = -1;
    else if (perimeterMag > 0) perimeterPID.x = 1; 
    else perimeterPID.x = 0;
  perimeterPID.w = 0;
  perimeterPID.y_min = -motorSpeedMaxPwm;
  perimeterPID.y_max = motorSpeedMaxPwm;		
  perimeterPID.max_output = motorSpeedMaxPwm;
  perimeterPID.compute();
  //setMotorPWM( motorLeftPWMCurr  +perimeterPID.y, 
  //               motorRightPWMCurr -perimeterPID.y, false);      
  setMotorPWM( max(-motorSpeedMaxPwm, min(motorSpeedMaxPwm, motorSpeedMaxPwm/2 - perimeterPID.y)), 
                 max(-motorSpeedMaxPwm, min(motorSpeedMaxPwm, motorSpeedMaxPwm/2 + perimeterPID.y)), false);      
  Console.print(perimeterPID.x);
  Console.print("t");          
  Console.println(perimeterPID.y);  
}


Now everything is working, the mower mows my lawn and finds back. He can track the perimeter ... :unsure:

I have some images after 50 minutes of mowing (the battery was not 100% full, I hope the mower reaches 1h mow-time with a full battery). It was a very rainy time, so I made photos of all the water inside of the mower. There were nearly 35 l/m² water in this 50 minutes :) ... poor mower :evil:

Greets,
Jem
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/1536/20150906_140533.jpg/
 
Zuletzt bearbeitet von einem Moderator:
I meant mower.cpp

Good that it works now :)

Uncommenting these line should not have any influence on the actual behavior.... Could it be that you made the fix and somehow the upload of the sketch did not work so that you continued to test with the original code?

Frederic
 
Second batch of pictures and robot.cpp and mower.cpp

I have a separate folder for the sketch-project, which I upload on the mower. So I am sure, that I used the modified version.

In the log-file you can see the PID.y-values ...

Greets,
Jem

Edit:
[video width=425 height=344 type=youtube]_r_58Dr1rHk[/video]

Edit2:
As the *.cpp-files do not like to be attached, I uploaded it on my own server.
Mower.cpp
Robot.cpp
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/1536/20150906_140746.jpg/
 
Zuletzt bearbeitet von einem Moderator:
Very odd :unsure:

So if you would comment the lines

Code:
Console.print(perimeterPID.x);
  Console.print("t");          
  Console.println(perimeterPID.y);

again, the problem comes back?

BTW, your mower looks very nice B)

Frederic
 
As I read your post from today about the motor-bug.

I realized, that I have changed the Sebsatian-changed-azurit-version to a new one ... maybe, this is the reason why it works now? Maybe you have seen it in the robot.cpp?


Code:
//JEMI TRIED HIS BEST
void Robot::setMotorPWM(int pwmLeft, int pwmRight, boolean useAccel){
  unsigned long TaC = millis() - lastSetMotorSpeedTime;    // sampling time in millis
  lastSetMotorSpeedTime = millis();  
  if (TaC > 1000) TaC = 1;
  
  if (useAccel){  
    // [URL]http://phrogz.net/js/framerate-independent-low-pass-filter.html[/URL] 
    // smoothed += elapsedTime * ( newValue - smoothed ) / smoothing;          
    motorLeftPWMCurr += TaC * (pwmLeft - motorLeftPWMCurr) / motorAccel;
    motorRightPWMCurr += TaC * (pwmRight - motorRightPWMCurr) / motorAccel;   
  }
  // ----- driver protection (avoids driver explosion) ----------
  if ( ((pwmLeft < 0) && (motorLeftPWMCurr >= 0)) ||
       ((pwmLeft > 0) && (motorLeftPWMCurr <= 0)) ) { // changing direction should take place?
    if (motorLeftZeroTimeout != 0)
      pwmLeft = motorLeftPWMCurr - motorLeftPWMCurr *  ((float)TaC)/200.0; // reduce speed
  }
  if ( ((pwmRight < 0) && (motorRightPWMCurr >= 0)) ||
       ((pwmRight > 0) && (motorRightPWMCurr <= 0)) ) { // changing direction should take place?    
    if (motorRightZeroTimeout != 0) // reduce motor rotation? (will reduce EMF)      
      pwmRight = motorRightPWMCurr - motorRightPWMCurr *   ((float)TaC)/200.0;  // reduce speed
  }
  
  if (odometryUse){
    if (abs(motorLeftRpmCurr) <1) motorLeftZeroTimeout = max(0, ((int)(motorLeftZeroTimeout - TaC)) );
      else motorLeftZeroTimeout = 500;
    if (abs(motorRightRpmCurr) <1) motorRightZeroTimeout = max(0, ((int)(motorRightZeroTimeout - TaC)) );      
      else motorRightZeroTimeout = 500;
  } else {
    if (pwmLeft == 0)  motorLeftZeroTimeout = max(0, ((int)(motorLeftZeroTimeout - TaC)) );
      else motorLeftZeroTimeout = 700;  
    if (pwmRight == 0) motorRightZeroTimeout = max(0, ((int)(motorRightZeroTimeout - TaC)) );      
      else motorRightZeroTimeout = 700;  
  }
  
  motorLeftPWMCurr = pwmLeft;
  motorRightPWMCurr = pwmRight;
  
  // ---------------------------------
  if (motorLeftSwapDir)  // swap pin polarity?
    setActuator(ACT_MOTOR_LEFT, -motorLeftPWMCurr);
  else
    setActuator(ACT_MOTOR_LEFT, motorLeftPWMCurr);
  if (motorRightSwapDir)   // swap pin polarity?
    setActuator(ACT_MOTOR_RIGHT, -motorRightPWMCurr);
  else 
    setActuator(ACT_MOTOR_RIGHT, motorRightPWMCurr);
}


It is nearly the same, you coded in the developer-folder :) That seems to be the proof, that your bug-fixing was successful ;-)



Code:
//DEVELOPER FOLDER
void Robot::setMotorPWM(int pwmLeft, int pwmRight, boolean useAccel){
  unsigned long TaC = millis() - lastSetMotorSpeedTime;    // sampling time in millis
  lastSetMotorSpeedTime = millis();  
  if (TaC > 1000) TaC = 1;

  if (useAccel){  
    // [URL]http://phrogz.net/js/framerate-independent-low-pass-filter.html[/URL] 
    // smoothed += elapsedTime * ( newValue - smoothed ) / smoothing;          
    motorLeftPWMCurr += TaC * (pwmLeft - motorLeftPWMCurr) / motorAccel;
    motorRightPWMCurr += TaC * (pwmRight - motorRightPWMCurr) / motorAccel;   
  }

  // ----- driver protection (avoids driver explosion) ----------
  if ( ((pwmLeft < 0) && (motorLeftPWMCurr >= 0)) ||
       ((pwmLeft > 0) && (motorLeftPWMCurr <= 0)) ) { // changing direction should take place?
    if (motorLeftZeroTimeout != 0)
      pwmLeft = motorLeftPWMCurr - motorLeftPWMCurr *  ((float)TaC)/200.0; // reduce speed
  }
  if ( ((pwmRight < 0) && (motorRightPWMCurr >= 0)) ||
       ((pwmRight > 0) && (motorRightPWMCurr <= 0)) ) { // changing direction should take place?    
    if (motorRightZeroTimeout != 0) // reduce motor rotation? (will reduce EMF)      
      pwmRight = motorRightPWMCurr - motorRightPWMCurr *   ((float)TaC)/200.0;  // reduce speed
  }

  motorLeftPWMCurr = pwmLeft;
  motorRightPWMCurr = pwmRight;

  if (odometryUse){
    if (abs(motorLeftRpmCurr) <1) motorLeftZeroTimeout = max(0, ((int)(motorLeftZeroTimeout - TaC)) );
      else motorLeftZeroTimeout = 500;
    if (abs(motorRightRpmCurr) <1) motorRightZeroTimeout = max(0, ((int)(motorRightZeroTimeout - TaC)) );      
      else motorRightZeroTimeout = 500;
  } else {
    if (pwmLeft == 0)  motorLeftZeroTimeout = max(0, ((int)(motorLeftZeroTimeout - TaC)) );
      else motorLeftZeroTimeout = 700;  
    if (pwmRight == 0) motorRightZeroTimeout = max(0, ((int)(motorRightZeroTimeout - TaC)) );      
      else motorRightZeroTimeout = 700;  
  }

  // ---------------------------------
  if (motorLeftSwapDir)  // swap pin polarity?
    setActuator(ACT_MOTOR_LEFT, -motorLeftPWMCurr);
  else
    setActuator(ACT_MOTOR_LEFT, motorLeftPWMCurr);
  if (motorRightSwapDir)   // swap pin polarity?
    setActuator(ACT_MOTOR_RIGHT, -motorRightPWMCurr);
  else 
    setActuator(ACT_MOTOR_RIGHT, motorRightPWMCurr);
}


Greets,
Jem
 
Indeed!

When you have odometry pulses disabled, both versions (Jemi and developer) are the same.
When you have odometry pulses enabled, Jemi's version will have as effect that the code works as if there are no odometry pulses...

Frederic
 
I will change Jemis Version to Dev Version to see if this is working too ... after that I will comment the console-output.

Greets, Jem
 
Hallo, habe in den letzten Tagen versucht eure Unterhaltung zu folgen. Ich kämpfe immer noch damit das sich mein Roboter auf der Perimeterschleife nur dreht, so wie es auch auf Deinem Video zu sehen war. Da mein Englisch sehr mager ist, könntest Du mir nochmal kurz erklären was genau Du angestellt hast damit das endlich funktioniert? Ich habe es einfach nicht verstanden. Vielen Dank im voraus, Gerd.

Ach ja, ich habe unter meinen einen Blumentopfuntersetzer geschraubt,den ich auf einer Seite aufgeschnitten habe. Dann schmaddert er sich nicht so voll mit dem Feuchten Gras.
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/2572/20150718_142928_2015-09-09.jpg/
 
Zuletzt bearbeitet von einem Moderator:
Mit der robot.cpp müsste es gehen.

Wenn nicht, probiere die Dinger aus, die ich oben mal gepostet habe. Bei mir lag es höchstwahrscheinlich an einer fehlerhaften Ansteuerung der Motoren. Das müsste mit der robot.cpp von Frederic behoben sein. Sollte es damit nicht gehen, dann nimm mal meine beiden Dateien, weil es damit bei mir funktioniert :)

Ich habe eine Rundumschürze aus dünnen Holzbrettchen an den Mäher geschraubt. Aber ich werde mal so einen Untersetzer runter setzen, sobald ich den Mäher das nächste Mal auf den Kopf stelle und die Mähscheibe abgenommen habe.

Gruß,
Jem
 
Oben