Best approach for vehicle state and logic?

I am in the planning of 'electronifying a zero turn mower.

Instead of the rather genius wiring, which creates AND, NOT and OR logic for the safety aspect and operation, I am planning to use a MEGA to implement (as a basis) the same functionality.

I have mocked-up the servo control for the throttle, choke, left and right hydrostats, which was relatively simple.
However, next is the logic. and this is where my question comes in seeking some experienced guidance.

The logic will require a seat switch to be ON before the deck can be engaged.
The engine can only be started if the brake is ON and the deck is OFF.
The engine cannot be started when the deck is ON or the seat is OFF.
... and so forth, and combinations of these.

How to best implement this logic in software?

Should I set and read bits? Use the bits as switches.
Should I use a state machine? Could be difficult due to conditions?
Should I use normal boolean variables? Very legible code compared to bit setting?!
Or any combination of the above?

I have attached the wiring diagram to provide an insight into the logic complexity or simplicity :slight_smile:

And why am I doing this?
Well, the next step is autonomy with ArduPilot (or rather ArduRover). The 'actuators need to be electronic, not mechanic. And I want to drive the mower in normal mode.

Sounds like you need to get you head around the idea of a "state machine". To do this, you can draw a diagram with a small box or circle representing each state, and arrows going between the boxes representing events. Label each box and arrow with the name of that state or event.

The machine can be in only one state at any instant in time. The only way for the machine to get out of a state is when one of the events/arrows leading away from the state happens, and the machine moves into the new state indicated by the arrow.

Start by listing all the states you can think of. You won't think of all of them at first. You will realise there are other states needed as you work through it.

Use pencil and paper so you can erase your mistakes and draw in the corrections. This will take a few iterations to get right. Post it here and we will help by reviewing it for you. Once the diagram looks reasonably good, we can advise how to code it. Coding it is actually the easier part. Getting that diagram right, with all the states and events, is the harder part.

3 Likes

My advice is to not think about how much memory the variables or code will use, but write code that is clear and good to read. Let the compiler worry about memory usage.

With bool operators you can do this:

bool deck;
bool seat;

if( seat and !deck)
{
  // seat is true and deck is false
}

A Finite State Machine can turn a hard logic puzzle into many small pieces of code. It is easy to maintain, but it is also easy to make a mistake. It might take some time before everything is free of bugs.
Do you know how to use a millis-timer with a Finite State Machine ? Once you get the hang of it, it is easy to combine timeouts and delays with a Finite State Machine.
If there are a few tasks that needs to run at the same time, then it is possible to have more than one Finite State Machine in the loop().

I think that you need a kill-switch that bypasses the Arduino Mega, in case electronic noise from the motor makes the Mega go haywire.

You have to find a good way to debounce the switches.

How are you going to develop the code ? Do you have a test setup with switches and leds ? You could even run it in a simulation.

The first step was to electronify the throttle, choke and hydros... and using rotary encoders for throttle and choke. I am still thinking about the encoders for the lap control arms (not important ATM).

Yes, I have switches simulating the real one; MG90S to simulate the servos, and LEDs.

Before running my head against a wall with the code, I asked here to get the basics right.

ATM I watching Youtubes on State Machines :slight_smile:

Will update as I go...

I like this tutorial: https://majenko.co.uk/blog/our-blog-1/the-finite-state-machine-26
On my Fun With Millis page, there are three examples of a Finite State Machine with millis(), search for "finite" or so.

1 Like

+1 for FSMs. Can I plus more than one? :wink:

Truer words never spoken or written.

I’m on a top secret effort right now and I’ll think of yet another aspect of the project, usually leading to an additional state, or modification to the roll and meaning of one already in there.

In the middle of the night. Or out at the beach. &c.

And there’s no reason to limit yourself to one FSM. They might or might not need to inform one another.

I am resisting writing code until I know I am very close. When that urge to code overcomes me, I try to find some low level detail to write a nice set of code for dealing with so I can get that part off my plate.

Does the original device have any safety mechanisms that are better than logic circuitry or code can ever be?

a7

Driving the mower in normal mode will have safety mechanisms the software.

In autonomous mode all safety features are disabled, except for an emergency stop, which is also functional in normal mode.

I initially only electronified the drive function, which are not in the diagram, because the mechanics is not wiring. So that was straight forward.

I would have used relays to 'interfere' at various points in the diagram to switch between auto and normal. This quickly became a mess and doe snot add to the reliability of the system.

Today I decided that I rip out the wiring harness, and add my own, which is simply feeding one contact with 12V and routing it to an input of the MEGA, and subsequently deal with the logic in software. Basically providing the factory functionality in software and electronics.

The future step is to switch the servo input from the MEGA to the pixhawk flight controller (and remote control if needed).

what is "deck"?

what about somewhat inverting the logic

    if (! seat)
        defeat engine (i.e. ground coil/magneto)
    else if (ignition switch ON)  {
        if (! brake)
            engage starter
    }

i don't see a need for a state machine

You need to think how you will add back the safety features you take off .

Hard wired logic has predictable failure modes , enacting these in software does not give anything like the same degree of safety .
You need to make sure it can’t start unattended , run down people or shred animals in much the same way as ensuring someone is on the seat does at the moment . So you might need bumper bars that stop it running etc …It’s probably the hardest part to get right .

I hope you understand that connecting 12V to an Arduino input will damage it? You need to use a voltage divider (== a pair of resistors) or for extra safety an opto-isolator.

pretty sure more switches pull something to ground.

The deck is the cutting deck of the mower.
When you look at the diagram (in the top/first post) you will see quite a few conditions, but I will certainly look into this.

This is not a commercial product; and the mower will run within a fully fenced property, without animals and people present.

es, I should have added that I;ll run most likely the 12V, and connect these via voltage dividers to the inputs.


Can I kindly ask to focus on the programming method, as in:

How to best implement this logic in software?

Should I set and read bits? Use the bits as switches.
Should I use a state machine? Could be difficult due to conditions?
Should I use normal boolean variables? Very legible code compared to bit setting?!
Or any combination of the above?

I fully understand that there are many other aspects to consider when building such a machine. Any collision or obstacle recognition can be added at a later stage... and treated like a binary input.
Also, the whole automation/autopilot is a topic for another day.

I simply want to cover here the approach of bit-banging, state machines, and or discrete logic.

Safety ?

Read me

I think we already answered the implementation questions more or less.
No logic in bits please. Trying to save one and a half bit while making the code less good to read is bad.
A Finite State Machine might be needed or not. They way you present the project, then it might not be needed, but along the way it might be needed and it does not hurt. Many conditions together with a Finite State Machine is no problem at all.

I have my own approach. When a sketch needs a Finite State Machine, then the sketch itself evolves into a Finite State Machine. I just sit there, looking at the sketch and see how it evolves.
You should hear me talk about the balloons with strings analogy: See every function/task as a balloon and the balloons are connected by strings, and the data is traveling over the strings.

1 Like

I am very much into safety. And as stated this post is about the logic approach only.
There will be sensors, both electronic and mechanical, to aid the safety aspect. All these sensor will be served by I single kill switch input, which does what it is happening now = kill the engine, thus stopping movement and blades.

These are my overarching principles:

A control circuit used to control the plant should be designed in accordance with the
requirements of the category, performance level or safety integrity level determined by a risk assessment. In particular:

  • the plant should not start unexpectedly
  • the plant should not be prevented from stopping if such a command has already been
    given
  • no moving part of the plant or work piece being held by the plant should fall or be ejected
  • automatic or manual stopping of moving parts should not be impeded, and
  • the protection device should remain fully effective or fail to a condition that does not create a risk.

Yes, looking at this as we speak... :slight_smile:
Certainly ditched the bit banging approach.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.