How I reduce vibration when tracking

I tested at pwm=250 with latest Github addition which is probably little too high. However most of my perimeter was working just fine. Except one corner next to the rainwater bucket where it got to an endless loop. So I reduced the default PWM to a ?safe? value of 200. Here are the additions of today.
Maybe a PID optimization could still improve.
I will push to Ardumower/ardumower since the code is working on 3 mower now.
https://youtu.be/yg1W7pRKJ7Q
Chris
 
@Holoratte.
What's the value of your PerimeterTimeout ?
Normaly if you put a timeout a 1500ms the mower need to stay on the wire.
Remenber If during this Timeout the mower move more than 2* the distance between Wheel and coil the wire is lost and the mower turn,Solution reduce the speed or reduce the timeout.
Here a funny video at full speed (/2 and /1.5 are remove) look at the second turn
The Timeout is set at 2500ms and during this time the mower move more than 2* distance Wheel coil and can't find the wire again when turn.

https://www.youtube.com/watch?v=OueZC03N_40
 
With PWM=200 and transitionTimeout of 1500s it was working just fine...
PID needs to be tuned!
This can be done in the Pfod. So should be just fine.

Chris
 
I think now it's working very good.

One idea regarding fast tracking and high angle :
Normaly when all is good, value is near/around zero. Why not start Wheel blocking imediately when difference (paritrack value) is increasing or exceed any limit = sooner than transitionTimeout will occur ?

Alex
 
Or we use a running average PID.error value to control the speed. This way it could self adjust the speed in curves. When the error is to big slowing down.
 
Hi.
Are you sure you correctly understand the timeoutvalue ?.

Normaly in curve or angle60deg and remember that the PerimeterMag is refresh only each 30ms the Pid don't have time to react so the in out transition don't occur for a periode superior at the timeout ,normaly if the pid work well one of the Wheel run fast and the other very slow and it's time to block it and put the other to fast to make a circle and find the in out transition again.
At this moment you can't run again with the total PID or the mower oscilate a lot so it's why (The last update) during 3000ms the PID action is proportionnal to the time,after this 3000ms normaly the fast tracking can start again.

All of this work perfectly at mowing speed on my denna , but as i use a due the perimeter is read each 15ms so the PID is compute 2 time faster than on the mega so the PWM send to Wheel also.

Again note that the PerimeterTimeout depend only of the distance between coil and Wheel and the speed of the tracking and maybe can be calculate.But this only complique the code.

It's not very easy for me to explain all yhis in English but i hope it's clear.

Thanks.
 
Just thinking how to avoid that overshouting...
What happend to the magnetic field at a 90 deg corner? Could it be detected before the mower is there?
I guess the difference or ratio between inside to outside mag would change before the corner...
 
Try this. How does it work?
trythis.png

Attachment: https://forum.ardumower.de/data/media/kunena/attachments/2936/trythis.png/
 
Zuletzt bearbeitet von einem Moderator:
What happend to the magnetic field at a 90 deg corner? Could it be detected before the mower is there?
Ok very good question .
And if it's possible maybe we can reduce the speed
Did you make some tracking test at the same speed of mowing ?
Because with my mower at normal speed (PWM 160) All is perfect.
 
At PWM= 160 and /1.5 SheepSheep sometimes struggles getting up that small hill where it lost the perimeter in my last video with too fast speed (PWM 255).
Its a traction problem, so maybe not right thread here.
At PWM = 200 it can get up and get the corner, so actually no problem.
I also only have 45deg corners. But anyway it would be nice to also master sharp corners without a transition timeout.
The 50cm with 45deg corners is about what you can see in my last video just before at the small lavender field. This is not an issue i guess.
 
one more question to the new code :


Code:
//PID controller: track perimeter
void Robot::motorControlPerimeter() {

//3 states
//wire is lost
//On the wire staright line pid fast action
//Back slowly to the wire pid soft action


//Control the perimeter motor only each 30ms
  if (millis() < nextTimeMotorPerimeterControl) return;
  nextTimeMotorPerimeterControl = millis() + 30; //possible 15ms with the DUE
  //tell to the pid where is the mower   (Pid.x)
  perimeterPID.x = 5 * (double(perimeterMag) / perimeterMagMaxValue);
  //tell to the Pid where to go (Pid.w)
  if (perimeterInside) {
  perimeterPID.w = -0.5;
  }
  else {
    perimeterPID.w = 0.5;
  }
  //parameter the PID 
  perimeterPID.y_min = -motorSpeedMaxPwm ;
  perimeterPID.y_max = motorSpeedMaxPwm ;
  perimeterPID.max_output = motorSpeedMaxPwm ;
//and compute
  perimeterPID.compute();


Why in definition for PID we have motorSpeedMaxPwm and not MaxSpeedperiPwm ?
 
@Alda.
Thanks.
Yes i forget these lines
Please make the change .
We need to use the MaxSpeedperiPwm.
I try to edit my Post.
 
One more idea.
In perimeter find is perimeterFind function:


Code:
// check perimeter while finding it
void Robot::checkPerimeterFind(){
  if (stateCurr == STATE_PERI_FIND){
    if (perimeterInside) {
      // inside
      if (motorLeftSpeedRpmSet != motorRightSpeedRpmSet){      
        // we just made an 'outside=>inside' rotation, now track
        setNextState(STATE_PERI_TRACK, 0);    
      }
    } else {
      // we are outside, now roll to get inside
      motorRightSpeedRpmSet = -motorSpeedMaxRpm  / 1.5;
      motorLeftSpeedRpmSet  = motorSpeedMaxRpm / 1.5;
    }
  }
}


and here we are working with motorSpeedMaxRpm. I think it isn't best solution and I think also here we must work with MaxSpeedperiPwm.

Why?
Because then we have setup :
MaxSpeedperiPwm - for all movements linked to perimeter (finding/tracking)
motorSpeedMaxRpm - for all movements linked to cutting with odometry
motorSpeedMaxPwm - for all movements linked to cutting without odometry

Alex
 
@Alda.
Yes i agree with you but in fact in my Denna Platform i constate that the MaxSpeedperiPwm is 180 and the motorSpeedMaxPwm is 180 also.
In my code i easily change the MaxSpeedperiPwm in Pfod so i can make a lot of test with different speed and the final is that the 2 value are the same.

If you want i can tell you how to add this change in Pfod and Save this value.

Also i have made a record on all main value in tracking each 15ms and the result is very good.

Again Yes it's a good idea to have a value for each working state so the user can easily adjust.

Thanks.
 
Bernard schrieb:
@Alda.

If you want i can tell you how to add this change in Pfod and Save this value.

Thanks.

Yes, sure, I'm interested about your solution
thanks
Alex
 
Zuletzt bearbeitet von einem Moderator:
@Alda
I don't know the version of Azurit you have but the Main to DO.
In the code I leave you the 3 or 4 existing line so you can easily find where to add

In Robot.cpp in void Robot::loadSaveUserSettings(boolean readflag) section to save the new MaxSpeedperiPwm value

Code:
eereadwrite(readflag, addr, bluetoothUse);
  eereadwrite(readflag, addr, esp8266Use);
  eereadwriteString(readflag, addr, esp8266ConfigString);
  //bb
  eereadwrite(readflag, addr, MaxSpeedperiPwm);


Only the last line after //bb need to be added


Now In Pfod.cpp to change the value

First make a search of "e18" with Ctrl F to be sure it's not exist in your Azurit Version.
If not exist then add line in

void RemoteControl::processPerimeterMenu(String pfodCmd) {
and in
void RemoteControl::sendPerimeterMenu(boolean update) {

The result you need to have

Code:
void RemoteControl::sendPerimeterMenu(boolean update) {
  if (update) serialPort->print("{:"); else serialPort->print(F("{.Perimeter`1000"));
  serialPort->print(F("|e00~Use "));
  sendYesNo(robot->perimeterUse);
  serialPort->println(F("|e02~Value"));
  serialPort->print(robot->perimeterMag);
  if (robot->perimeterMag < 0) serialPort->print(" (inside)");
  else serialPort->print(" (outside)");
  sendSlider("e08", F("Timed-out if below smag"), robot->Perimeter.timedOutIfBelowSmag, "", 1, 500);
  sendSlider("e14", F("Timeout (s) if not inside"), robot->Perimeter.timeOutSecIfNotInside, "", 1, 20, 1);
  sendSlider("e04", F("Trigger timeout"), robot->perimeterTriggerTimeout, "", 1, 1000);
  sendSlider("e05", F("Perimeter out roll time max"), robot->perimeterOutRollTimeMax, "", 1, 8000);
  sendSlider("e06", F("Perimeter out roll time min"), robot->perimeterOutRollTimeMin, "", 1, 8000);
  sendSlider("e15", F("Perimeter out reverse time"), robot->perimeterOutRevTime, "", 1, 8000);
  sendSlider("e16", F("Perimeter tracking roll time"), robot->perimeterTrackRollTime, "", 1, 8000);
  sendSlider("e17", F("Perimeter tracking reverse time"), robot->perimeterTrackRevTime, "", 1, 8000);
  sendSlider("e18", F("Tracking Max Speed PWM"), robot->MaxSpeedperiPwm, "", 1, 255);


and


Code:
void RemoteControl::processPerimeterMenu(String pfodCmd) {
  if (pfodCmd == "e00") robot->perimeterUse = !robot->perimeterUse;
  else if (pfodCmd.startsWith("e04")) processSlider(pfodCmd, robot->perimeterTriggerTimeout, 1);
  else if (pfodCmd.startsWith("e05")) processSlider(pfodCmd, robot->perimeterOutRollTimeMax, 1);
  else if (pfodCmd.startsWith("e06")) processSlider(pfodCmd, robot->perimeterOutRollTimeMin, 1);
  else if (pfodCmd.startsWith("e15")) processSlider(pfodCmd, robot->perimeterOutRevTime, 1);
  else if (pfodCmd.startsWith("e16")) processSlider(pfodCmd, robot->perimeterTrackRollTime, 1);
  else if (pfodCmd.startsWith("e17")) processSlider(pfodCmd, robot->perimeterTrackRevTime, 1);
  else if (pfodCmd.startsWith("e18")) processSlider(pfodCmd, robot->MaxSpeedperiPwm, 1);



Only the line concerning the MaxSpeedperiPwm need to be added normaly the other exist already.

If i forget Nothing you can now change the value and save it.

To be sure it's work simply put a value of 50, save setting Shutdown the mower And normaly when Power on again the value stay to 50.

Be carreful that with Mega i think i need to stop the tracking before change the value.

Hope it's OK.
 
Hi Alda.
What you find in mower.cpp is the factory setting and use only the first time you reset the Arduino or with the factory setting on Pfod menu.
But when you change a value in setting menu and save setting, The new value stay for all time (change only when new factory setting).

So if you change the MaxSpeedperiPwm in pfod setting and save it the new value is save for all time (or change only when new factory setting).
Hope i forget Nothing but normaly it's work perfectly.
 
Oben