Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Fuzzy Yacht Autopilot

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here
View previous topic :: View next topic  
Author Message
snipsnip

Bascom Member



Joined: 10 Feb 2014
Posts: 74
Location: Melbourne

australia.gif
PostPosted: Mon Feb 19, 2024 11:38 pm    Post subject: Fuzzy Yacht Autopilot Reply with quote

I know this is a forum for working code, and this is very much a work in progress, Sorry

Thought Id share a simple triangle membership function I'm working on. Just in case I'm way off course with all this.
Eventually - the aim is to have a simple feedback system to auto tune these arrays. I've still got a heap of work to do on it first.

Just looking for ideas on what people have done before.
Cheers




Code:



'/ #tuneable
call BuildHeadingDeviationMember(1,25,20,70,50,100)
call BuildROCMember(1,49,40,60,51,100)

headingDeviation = 20 '/the error input value, map to 100 and peg extremes
fuzzyDeviation(1)=good(HeadingDeviation)
fuzzyDeviation(2)=nominal(HeadingDeviation)
fuzzyDeviation(3)=shit(HeadingDeviation)

ROC = 50              '/ degs/sec input mapped to 0 to 100 for normal range - peg extremes
fuzzyROC(1)=Slow(ROC)
fuzzyROC(2)=Average(ROC)
fuzzyROC(3)=Fast(ROC)


sub BuildHeadingDeviationMember(byval goodstart as byte,byval goodend as byte,byval nominalstart as byte, byval nominalend as byte,byval shitstart as byte, byval shitend as byte)

   local tmp as single ,tmp1 as single,tmp2 as single,tmp3 as single
   local angle as single, yaxis as single
   local base as byte ,t as byte, ctr as byte

  ''/-good-

   tmp1 = 100/goodend : angle = atn(tmp1) '/ RAD
   base = goodend
   for t = 0 to 100
      if base < goodend then yaxis = base * TAN(ANGLE)
      if base > goodend then yaxis = 0
      Good(t) = int(yaxis)
      decr base
   next t

  ''/-nominal-

   tmp1 = nominalend - nominalstart: tmp1=tmp1 / 2 :ctr = tmp1 + nominalstart
   tmp2 = 100/tmp1 : angle = atn(tmp2)

   base = 0
   for t = 1 to ctr
      if t < nominalstart then yaxis = 0
      if t > nominalstart then yaxis = base * TAN(ANGLE)
      nominal(t) = int(yaxis)
      if t => nominalstart then incr base
   next t

   base = NominalEnd - ctr
   for t = ctr to 100
      if t > NominalEnd then yaxis = 0
      if t < NominalEnd then yaxis = base * TAN(ANGLE)
      Nominal(t) = int(Yaxis)
      if t =< NominalEnd then decr base
   next t

  ''/-shit-

   tmp = 100 - ShitStart
   tmp1 = 100 / tmp : angle = atn(tmp1)
   base = tmp

   for t = 100 to 0 step -1
      if base < ShitStart then Yaxis = base * TAN(angle)
      if base > GoodEnd then yaxis = 0
      shit(t) = int(yaxis)
      decr base
   next t
end sub


 
 


Last edited by snipsnip on Fri Feb 23, 2024 1:54 am; edited 3 times in total
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5922
Location: Holland

blank.gif
PostPosted: Tue Feb 20, 2024 8:31 pm    Post subject: Reply with quote

thanks for sharing. I have no experience with this but i am sure it is of interest to others. lets see Smile
_________________
Mark
Back to top
View user's profile Visit poster's website
Per Svensson

Bascom Member



Joined: 03 Oct 2004
Posts: 235
Location: Gothenburg, Sweden

sweden.gif
PostPosted: Wed Feb 21, 2024 1:36 pm    Post subject: Reply with quote

Hi Snipsnap,

I worked on an autopilot for my 10m sailboat some years ago.
Unfortunately I can not guide you along the Fuzzy road as I know nothing about it. Mine was based in PID.
I learnt that finding the right control parameters is virtually impossible as the conditions (wind, waves, tilt) is changing with weather
so much that they must be dynamically controlled all the time. Perhaps fuzzy can do this?
Mine worked fine in decent conditions, but had problem with stability when sea got rough.

I have worked all my life with inertial sensors, so getting the indata is not a problem. The challenge is to trim the gains.
If I would do this again today, I would certainly look at artificial intelligence

Good luck
/Per
Back to top
View user's profile Visit poster's website
snipsnip

Bascom Member



Joined: 10 Feb 2014
Posts: 74
Location: Melbourne

australia.gif
PostPosted: Wed Feb 21, 2024 2:45 pm    Post subject: Reply with quote

Per Svensson wrote:
Hi Snipsnap,

I worked on an autopilot for my 10m sailboat some years ago.
Unfortunately I can not guide you along the Fuzzy road as I know nothing about it. Mine was based in PID.
I learnt that finding the right control parameters is virtually impossible as the conditions (wind, waves, tilt) is changing with weather
so much that they must be dynamically controlled all the time. Perhaps fuzzy can do this?
Mine worked fine in decent conditions, but had problem with stability when sea got rough.

I have worked all my life with inertial sensors, so getting the indata is not a problem. The challenge is to trim the gains.
If I would do this again today, I would certainly look at artificial intelligence

Good luck
/Per


Hi mate, you inspired me to look into this with your Kalman filter imu examples. They were a bit too full on for me to get my head around and adapt to a pilot though. At least with fuzzy, while still a bit complicated - the maths is easy to understand and tweak. (from what I have gathered so far)

Re - changing conditions... There's only so many member functions and resulting lookup tables that can fit into a little avr memory.
still though, from what I've read so far it should be ok. (as long as the model is close, this is the very hard bit imo) No complex maths involved to build it, just intuition or a heap of data. I'm only doing this for fun - but if I can get something workable, i'll ditch the current tiller pilot and run it.

Cheers mate.
Back to top
View user's profile
Per Svensson

Bascom Member



Joined: 03 Oct 2004
Posts: 235
Location: Gothenburg, Sweden

sweden.gif
PostPosted: Wed Feb 21, 2024 3:16 pm    Post subject: Reply with quote

By the way...

I did try an simple type of AI for PID parameter optimisation when I was up to it.
I tried a method called "Genetic Algorithms". It is a technique that mimics the natural evolution of life
You know - "Evolution always finds a way" You can read more about it here if you like.
https://se.mathworks.com/help/gads/what-is-the-genetic-algorithm.html

The result was rather poor though. Not because the method is bad, but because the training is hard.
I really never found an automated way to describe to the system what a good boat steering should look like.
The method demands a repetitive "Steer the boat using trained parameters" . Then "Check if things have improved
with these new parameters compared to a previous set of params ". Then "Generate a set of parameters including some randomness"
Then test each new candidate and kill those that performed worst. Then breed last good known set with this new candidate...
Etc... etc... over and over until evolution finds an optimum set of params..

Well - In theory it works, but hard to find a selection criteria.
Modern AI is using smarter algorithms Very Happy

/Per
Back to top
View user's profile Visit poster's website
snipsnip

Bascom Member



Joined: 10 Feb 2014
Posts: 74
Location: Melbourne

australia.gif
PostPosted: Fri Feb 23, 2024 1:22 am    Post subject: Reply with quote

This is the basic outline of what I'm looking to implement..

https://www.youtube.com/watch?v=TReelsVxWxg
Go to around the 50 min mark for the nitty gritty

I'll be using something like these below as member functions fed from a BNO085 imu and gps

heading deviation
rate of change in heading

speed of boat
acceleration of boat [x,y,z] axis

the (looped through) combination of these will then generate a lookup table / array with the steering output.
any tuning change and the table will need to be regenerated. I don't think the avr could do the calcs live.

Hopefully this should be enough to judge sea state and spit out a decent rudder angle / rate command to suit.
Back to top
View user's profile
snipsnip

Bascom Member



Joined: 10 Feb 2014
Posts: 74
Location: Melbourne

australia.gif
PostPosted: Mon Mar 04, 2024 12:01 pm    Post subject: Reply with quote

Here's where I'm at with the rule / inference block.

Code:

''/ -------------heading error / accel get merged and defuzzed to produce rudder rate of change---------------
''/ HeadingDeviation aka error = value returned from navigation function #wip
HeadingDeviation =  byteMap(V,0,30,0,100) '/ crisp input, replace v with input

'/ HOLDS THE % VALUES EACH MEMBER FUNCTION
FuzzyDeviation(1) = Good(HeadingDeviation)
FuzzyDeviation(2) = Nominal(HeadingDeviation)
FuzzyDeviation(3) = Shit(HeadingDeviation)

''/Accel is a value of "seastate" returned from a function that either merges, normalise or maxes imu accel x,y,z  outputs?
Accel = byteMap(V,0,30,0,100)' #test
FuzzyAccel(1) = Calm(accel)
FuzzyAccel(2) = Choppy(accel)
FuzzyAccel(3) = Ruff(accel)

'/convert input member functions to a 1,2,3 definition.  1=L 2=M 3=H
Max(Fuzzydeviation(1), dev_val, dev_mem) '/ ###_mem is the index # of the highest value of the fuzzy array
Max(FuzzyAccel(1), sea_val, sea_mem)     '/ ###_val is the value of the highest value of the array


'/ MERGE RULES - THIS DECIDES WHICH RUDDER RATE OUTPUT MEMBER FUNCTION GETS LOADED
if Dev_Mem = 3 and Sea_Mem= 3 then OP_MF= 3
if Dev_Mem = 3 and Sea_Mem= 2 then OP_MF= 3
if Dev_Mem = 3 and Sea_Mem= 1 then OP_MF= 2
if Dev_Mem = 2 and Sea_Mem= 3 then OP_MF= 2
if Dev_Mem = 2 and Sea_Mem= 2 then OP_MF= 1
if Dev_Mem = 2 and Sea_Mem= 1 then OP_MF= 1
if Dev_Mem = 1 and Sea_Mem= 3 then OP_MF= 2
if Dev_Mem = 1 and Sea_Mem= 2 then OP_MF= 3  '/ high here as this is where the control should home in on
if Dev_Mem = 1 and Sea_Mem= 1 then OP_MF= 3  '/ and once in this region we want fast response to keep it there????


 '/ load the mf values into an array for the MF_height to work with

select case OP_MF

   case 1:'/ lo value MF
      if dev_val > sea_val then
         MF_height(1) = dev_val
         MF_height(2) = sea_val
         MF_height(3) = 0
      else
         MF_height(1) = sea_val
         MF_height(2) = dev_val
         MF_height(3) = 0
      end if


   case 2:'/ med value MF
      if dev_mem > sea_mem then  '/ not a typo re:- the mem
         MF_height(1) = sea_val
         MF_height(2) = dev_val
         MF_height(3) = 0
      else
         MF_height(1) = 0
         MF_height(2) = sea_val
         MF_height(3) = dev_val
      end if
     '/ ^this is garbage, need a better way.


   case 3:'/ hi value MF
      if dev_val > sea_val then
         MF_height(1) = 0
         MF_height(2) = sea_val
         MF_height(3) = dev_val
      else
         MF_height(1) = 0
         MF_height(2) = dev_val
         MF_height(3) = sea_val
      end if

end select

'/MERGE the three defuzz member triangles into one array with heights capped as per above
for n=1 to 100
   if  HeadAccel_Low_Defuzz(n) >= MF_height(1) then HeadAccel_merged_Defuzz(n) = MF_height(1)
   if  HeadAccel_med_Defuzz(n) >= MF_height(2) then HeadAccel_merged_Defuzz(n) = MF_height(2)
   if  HeadAccel_hi_Defuzz(n)  >= MF_height(3) then HeadAccel_merged_Defuzz(n) = MF_height(3)
next n




 


Last edited by snipsnip on Sat Mar 09, 2024 10:58 pm; edited 1 time in total
Back to top
View user's profile
Per Svensson

Bascom Member



Joined: 03 Oct 2004
Posts: 235
Location: Gothenburg, Sweden

sweden.gif
PostPosted: Mon Mar 04, 2024 5:11 pm    Post subject: Reply with quote

Hi Snipsnip

I followed the lecture to get some understanding of the Fuzzy control principle, and found it very amusing (or how I should put it..)
The Fuzzification part is straightforward (well, rather straightforward) But to generate the rules is really another story.
Interesting to see that the lecturer suggested Genetic Algo since this is something I can understand. But also know is hard to adopt.
And not only hard to adopt, but also to evaluate the result of, because the convergence is usually there, but often the found solution is not the maximum,
but a LOCAL maximum, which easily could fool you to believe you have found a decent solution, whilst we in reality have a poor solution.

Anyway, he also suggests other solutions, and especially evolutionary methods sounds interesting, so I will follow that track and listen to his next lecture too.
I guess you have already don that?

By the way. How do one know if a set of rules will generate a stable fuzzy output (Not causing oscillations etc). Are there stability criterias?

/Per
Back to top
View user's profile Visit poster's website
snipsnip

Bascom Member



Joined: 10 Feb 2014
Posts: 74
Location: Melbourne

australia.gif
PostPosted: Mon Mar 04, 2024 10:27 pm    Post subject: Reply with quote

Per Svensson wrote:
Hi Snipsnip

I followed the lecture to get some understanding of the Fuzzy control principle, and found it very amusing (or how I should put it..)
The Fuzzification part is straightforward (well, rather straightforward) But to generate the rules is really another story.

Interesting to see that the lecturer suggested Genetic Algo since this is something I can understand. But also know is hard to adopt.
And not only hard to adopt, but also to evaluate the result of, because the convergence is usually there, but often the found solution is not the maximum,
but a LOCAL maximum, which easily could fool you to believe you have found a decent solution, whilst we in reality have a poor solution.

Anyway, he also suggests other solutions, and especially evolutionary methods sounds interesting, so I will follow that track and listen to his next lecture too.
I guess you have already don that?

By the way. How do one know if a set of rules will generate a stable fuzzy output (Not causing oscillations etc). Are there stability criterias?

/Per


Yeah. the rules part had me scratching my head for a very long time. Just trying to understand the concept and how and why it links everything.
re - local maximums and other methods... Thats the crazy part with this fuzzy stuff, literally every single thing is tuneable, everything!
I have no idea how well this implementation will work - if at all. <- i think i understand it and what's going on, I could be way off??



If stability is an issue I can add some more member functions around the oscillation points, but the logic rules can get big pretty quick with more MF's.
I was hoping and thinking if the rule block is assigned properly - stability should be inherent. ? I put some comments on the rule blocks (above) where I think these areas will be.

I have almost enough of a program now to loop through the entire input ranges and generate the output tables. I'll post the surface plots when I get it all working.


I think a genetic algorithm would work very well with this - but jesus - I'm struggling just getting my head around this, let alone another even more complex layer on top. Smile
Back to top
View user's profile
Per Svensson

Bascom Member



Joined: 03 Oct 2004
Posts: 235
Location: Gothenburg, Sweden

sweden.gif
PostPosted: Mon Mar 04, 2024 11:11 pm    Post subject: Reply with quote

https://www.youtube.com/watch?v=3-NiZPbkr7A
That guy is a good teacher. rather funny too, certainly know what he is talking about
I got a good recap of GA which was good since I have not been into it since 2011.

If you are interested in a thread I started about Genetic Algorithms you can have a look here:
https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=9274&highlight=genetic

The reason why I gave it up was that it was so slow to train the GA population , and also hard to find a fitness criteria.
Training each generation requires that you have to run the real process (the boat) for some minutes to se how well it behaves with the selected genome
and then from the fitness results generate another population via Crossover, cloning and mutation.
Running hundreds of evaluations take an awful lot of time. In addition it is not easy to maintain a reasonably consistent sea state for such a long time:
I would take a very long journey to get a result.

Fuzz logic is a new world for me although I have seen it around for many years, but really never taken the time to dig into it. But very interesting
The mathematical simplicity is very tempting. But on the other hand Kalman Filter math is also very simple, but not so easy to grasp and digest so somplicity
can be very deceiving.
/P

[/url]
Back to top
View user's profile Visit poster's website
snipsnip

Bascom Member



Joined: 10 Feb 2014
Posts: 74
Location: Melbourne

australia.gif
PostPosted: Tue Mar 05, 2024 12:16 am    Post subject: Reply with quote

Thanks for that, very interesting thread. a shame it's locked.

The way fuzzy works with sets should be well suited for a genetic algorithm to tune and test?

Now I want to see if I can implement that can of worms. Thanks!
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum