Let's Make Robots!

How to code "almost equals" or "pretty close"?

****Full code is attached****

In the code, b19 is increased all over the place. This variable is used in the "ran" select case subroutines to get a "random" move.

 

I use a simple subroutine for some of Walter's head moves. The calculation is simple, it is "where you are now" compared to "where you want to go". The sub routine knows "where the head is now" and recieves the 3 bytes as to "where the head should finish". It then calculates all the steps to get from A to B. In each loop, a check is made to see if we have gotten to our end point yet. Here is where my question lies. So here is the code:

servocalc:
for b11= 1 to 255 step 1
if b7>b4 then let b4=b4+b10 max b7
endif
if b4>b7 then let b4=b4-b10 min b7
endif
if b8>b5 then let b5=b5+b10 max b8
endif
if b5>b8 then let b5=b5-b10 min b8
endif
if b9>b6 then let b6=b6+b10 max b9
endif
if b6>b9 then let b6=b6-b10 min b9
endif
if b4=b7 and b5=b8 and b6=b9 then
return
endif
gosub servomove
pause 20
inc b19
next b11
return



servomove:
I2CSLAVE $C2, i2cslow, i2cbyte 'this is the i2c for the servo driver
writei2c 1,(b4)
writei2c 2,(b5)
writei2c 3,(b6)
pause b15
inc b19
return

Now, B4 B5 and B6 is where the head is now, and B7 b8 and b9 are where we are going. B10 is how big of steps we should take to get there (this is speed). The line at issue here is the one in bold.

if b4=b7 and b5=b8 and b6=b9 then
return
endif

If I use a value other than 1 in b10, the steps won't always add up to be an end number exactly and the line above will not ever be true. I need to code in something like this:

if b4=b7 +or- 2 and b5=b8 +or- 2 and b6=b9 +or-2 then return

 

AttachmentSize
playback_test_of_table_head_moves.bas5.48 KB

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I have found I have the same problem at the other end. You need to have room it seems for the min/max to catch stuff, I guess...

I have added this and everything is fixed. I still don't know why

lookupmove:
readtable b14,b7,b8,b9
if b7=1 then let b7=b10+1
endif
if b8=1 then let b8=b10+1
endif
if b9=1 then let b9=b10+1
endif
if b7>230 then let b7=254-b10
endif
if b8>230 then let b8=254-b10
endif
if b9>230 then let b9=254-b10
endif
return

The picaxe first calculates the number and then checks the MIN MAX rules so

b1 = b1 - b10 MIN b7

will wrap around when b1 - b10 < 0 because the result (<0) is a large number that will be compared with b7. 

e.g. b1=5 : b10=7 and b7 = 4

step 1) the picaxe calcs b1 - b10 = -2 => 253

step 2) compare result 253 with the number 4

step 3) concludes the outcome 253 > 4 and therefore doesn't need to be corrected to 4.

 

To make your code takes this into account with any speed setting on both ends of the byte, it should look like this.

let b0 = 255-b10

let b7 = b7 MIN b10 MAX b0

The mystery is almost put to bed. As am I.

This hard coded program demonstrates

b1 = 250                        ' 250
b1 = b1 + 9 max 252      ' 252 (as expected)

b1 = 6                        '    6
b1 = b1 - 9 min 2        ' 253 (wrap around)

Is it because internally the calculation is done in a word, but even words have a bottom value of zero?

Do you min'ing and max'ing BEFORE your subtracting and adding.

b1 = 250                        ' 250
b1 = b1 max 243 + 9      ' 252

b1 = 6                        '   6
b1 = b1 min 11 - 9       '   2

w1 = 65530                      ' 65530
w1 = w1 + 9 max 65532      '      3

w1 = 6                        '        6
w1 = w1 - 9 min 2        ' 65533

I added this to the "look up move routine" and it has solved all problems. It was the 1 and I don't know why.

lookupmove:
readtable b14,b7,b8,b9
if b7=1 then let b7=8
endif
if b8=1 then let b8=8
endif
if b9=1 then let b9=8
endif
return

That workaround will only work for step size 7 or less. Perhaps if you said
if b7=1 then let b7=b10
you would regain a flexible stepsize again.

BUT, what if b7 urns out to be 2, or 3? or 4 or 5 or 6 or 7? I propose (still a workkaound):
if b7 < b10 then b7 = b10
which is equivalent to
b7 = b7 min b10

ting? I don't think so. See my other comments for a better loop that needs no work around (just crossed fingers).

I just went through a lot of debugging data and found something weird... You are right, the code will goto and include the min/max number... Just not always! I saw a bunch of numbers where the last move did not equal the step used and the number was indeed "caught" by the min/max and became the min/max. Other times, it is missed. It seems that if the "going to" number is 1 it has issues. I am going to try another run-through converting 1 into a number bigger than the step used and see what happens.

I updated the post, there is a video showing the problem. Here is some sertxd data showing some numbers during the problem...

(This is stepping by 7)


<B4>38 <B5> 175 <b6> 64 'current servo pos
<B7> 1 <B8> 175 <b9> 64 'where we want to go --b8 and b9 have gotten there, just waiting for rotate to catch up
<B4>31 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64
<B4>24 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64
<B4>17 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64
<B4>10 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64
<B4>3 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64
<B4>252 <B5> 175 <b6> 64 '<<<< the loop starts over here. we want b7 to be one but it skips past and goes to 252.
<B7> 1 <B8> 175 <b9> 64
<B4>245 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64
<B4>238 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64
<B4>231 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64
<B4>224 <B5> 175 <b6> 64
<B7> 1 <B8> 175 <b9> 64

Only AFTER reaching one does it go "under". This tells me that your loop needs reprogramming indeed. Your code makes one more "loop for the road". Make it stop in time!

The do ... loop until construction elsewhere on this page will set you free.

*crosses fingers*