Boilevin / AzuritBer

Ardumower full odometry version
7 stars 13 forks source link

Consideration: Major code rewrite for AzuritBer to simplify and improve functionality #7

Open Geo-Ron opened 3 years ago

Geo-Ron commented 3 years ago

Hi @Boilevin,

I have spend the last week going through your code and I am really impressed on the motor control with odometry. I do not fully grasp the inner workings of the PID controller and some of the calculations you make, but that will come eventually 😉

I have seen that it has become a really complex state-machine, because of the old Azurit code remains and that you have created a new state for every operation/target. In my opinion this makes everything over-complex and hard to improve.

I am proposing a new/revised way of coding the Ardumower, that I want to contribute to your current code.

I would like to know your point of view on this method and would really like to accomplish this together, instead of creating my own standalone fork of your code. So please reply here and discuss.

Change the way the states are used

My thoughts would be that we use the following items:

In the code it would be wise (to my opinion) to honour the following rules:

My recommendations on the state improvements would be the following

States (these would be the actual action the robot is doing; the outputs)

Statuses (what major job am I doing)

Task (current task/substatus)

This task would consist of a few predefined STATES.

For example, avoid obstacle would be reverse, roll x degrees, circles around it for x meter, roll back to original heading and resume status.

Geo-Ron commented 3 years ago

Additionally, I have your AzuritBer Level 1 setup. With MPU6050 IMU and odometry. No compass. GPS unit will be added the next few months. This would be my testing unit for the revised firmware.

I saw you communicatie and interact states with the RaspberryPI via PFOD, so that would not be an issue but I am unable to test.

Boilevin commented 3 years ago

GPS unit will be added the next few months.

There is no code actually to really manage GPS and my result using raspberry tracking show (for standard GPS) a 10 meters accuracy. It's so bad that i stop to write code for this . SUNRAY and RTK is the solution but very expensive.

My recommendations on the state improvements would be the following

I agree with the description you make but I don't really understand because you describe the AZURITBER working mode and can't see what you really want to change except:

You want to add a task (Is it a kind of macro with some state inside ????)

every check on sensors would only return a variable about their status and not change the state directly

Yes it's a good idea.

you have created a new state for every operation/target. In my opinion this makes everything over-complex and hard to improve.

Using state for each operation help a lot in debugging and can smooth the motor drive control, You can use as many state as you want and it's very easy to understand and manage inside the code. For example simply search "case STATE_PERI_OBSTACLE_REV:" and you can find it 2 time the first one initialise the state "all value heading,speed, accel, OdoRampCompute" and the second one is the loop to check when it's time to go to a new state.

I can create a new "DEV" branch so we can make some test inside without braking the master one.

Actually something that can help inside the level 1 is the possibility to record the console inside ESP32 or 8266 and use a WebInterface to acces to it. Raspberry help a lot for debugging using console.

Geo-Ron commented 3 years ago

You have to think about the states the other way around.

The used of only technical machine states instead of functional will reduced the amount of code that needs to be maintained because of less duplicate code.

A few examples:

- Job/Status: NORMAL_MOWING
  - Task: DRIVE
  - Machine state: FORWARD

- Job/Status: NORMAL_MOWING
  - Task: TURN (because of perimeter reached, while mowing random)
  - Machine state: STOP_ROLLOUT, then DRIVE_BACKWARDS, then ROLL for random°, then DRIVE

- Job/Status: NORMAL_MOWING
  - Task: TURN (because of perimeter reached, while mowing lanes)
  - Machine state: STOP_ROLLOUT, then DRIVE_BACKWARDS, then ROLL for 135°, then DRIVE 20cm, then ROLL for 45°, then DRIVE

- Job/Status: NORMAL_MOWING
  - Task: AVOID_OBSTACLE (because of bumper or sonar triggered)
  - Machine state: STOP_HARD, then DRIVE_BACKWARDS, then ROLL for 45°, then CIRCLE around is, then ROLL to original heading, then DRIVE

- Job/Status: BACK_TO_STATION
  - Task: PERI_FIND
  - Machine state: ROLL to find strongest PERIMETER heading (or to set GPS coördinates), then DRIVE untill perimeter OUTSIDE

- Job/Status: BACK_TO_STATION
  - Task: PERI_TRACK
  - Machine state: ROLL to get Perimeter INSIDE, then PERI_TRACK untill found station by chgVoltage

I know you have abandoned the GPS usage, but I would like to use it for a fast_track to go back to station. Only a first drive heading to find the perimeter.

A DEV branch would be a good idea.