Navigation with (2) sonars Update 2 (with data)

I’m still getting up to speed with you guys, but…

I gotta be honest, telefox, I am just starting to learn this whole bit shifting thing. But in terms of picaxe doing it, does this help?

The X1 and X2 parts also support
<< ; shift left
>> ; shift right
*/ ; multiply (returns middle word of result)
DIG ; return the digit value
REV ; reverse a number of bits

Hey, those are the ones, I
Hey, those are the ones, I know I’d seen >> used as a shift operator somewhere =)
Fun fact, if you shift a binary number to the right one place, it’s the same as dividing it by two. Likewise, shift it to the left to multiply by two.

Some problems…

Well boys, we got a problem…

I just started coding the simple procedure of taking readings, set 1’s and 0’s and spit out some data via LCD. Well, guess what? I need more than 32 bits… …and 32 is all that this little chip has to offer. Not to mention, I need a few to run my encoders. Even if I reuse bits, I still don’t have enough. My far, middle, close ring idea still stands but each has to be done individually and stored as bytes. Upon decision making, these bytes have to be converted back to binary to be worked with, or the look-up table thing will have to work in real numbers. I guess the picaxe doesn’t care if it is thinking in bin. dec. or whatever, but for me (the human) it would have been nice to see all the readings in nice little packs of 8 on-off switches.

I am stiil in the KISS mode right now, so I am going to continue to code one ring right now and play around with the data I get. I figure that in the long run this is not a huge problem. During the main routine, I want to look for a path that is farthest out first. I will just have to check each ring individually. I.e. “is there a path @ fathest out?” -no?- “is there a path @ the middle ring?” -no?- “is there a path @ closest?” -no?- "you probably have close walls on 3 sides and need to turn 180 or back out"

This is what I got so far. I am still trying to wrap my head around this whole bit shifting thing, but one step at a time, I guess.

Thanks, guys.

 

Problem or request for help?

Not sure if you asked for this, but I am almost certain it is welcome:

Your coding problem with the 32 bits sounds like a limit from either a very small picaxe (08M?) or you are talking about bytes and storing each bit in a byte for representation purposes. I am guessing the second.

This can indeed be solved using the bit shifting (alt: AND’ing et OR’ing). Pack all bits into one (or more) bytes. When representing them (on your LCD) you don’t want to read “255” when in your mind it should be " 11111111". Even I would not tolerate such a debug method. So that means unpacking in a clever way. Probably displaying bits “on the go” - while unpacking the byte(s). Don’t store anything that’s ready to ship out.

I wrote a poc before that demonstrates the packing (was it also in the “may I go”-node?) using << et >>. On picaxes without the X-suffix, you’d have to user powers of 2 and simple adding. Let me know if you’re in the mood for some pseudo code. Just to get your mind a bit tiny amount expanded and prepared for your own experiments.

One more note about different types of variables: Only you (and all humans, with very few exceptions) care about them. The processor only “senses” zeroes and ones. Check the picaxe debug window. It displays “values” of variables in different ways. The actual “data” are in binary.

You mention that “… these bytes have to be converted back to binary to be worked with …”.
I’d prefer: “… iterate over the individual bits inside a byte …”. No conversion as such. No storing individual bits if you can help it. Consider your byte as a string of bits, like a sentence can be a string of characters.

Code, sure!

You know, rik I went back and reread the may i go post, a lot of it still applies.

I would love some psuedo code on this whole bit shifting thing. And yes, it is about packing and unpacking bytes into bits just so I can see them on the screen. And yes again, even a picaxe x2 only allows 4 bytes to be broken down to individual bits. If I want to tell an individual bit to be on or off, I can only do it up to bit31.

Converting to bits to work with them… yeah, I know, I was referring again to me, the human, seeing them.

 

Been looking at the data
Welll, when I wrote down all 16 bits in a row and things seemed much better. I also had a great idea about the 2 bytes issue. Now I know you guys have this bit shifting thing going but really, wouldn’t it be easier just to lower the resolution? It should be easy to take the 3 readings at each distance point and then simply convet to a byte for the total arc. Sure, 8 points for the whole arc, but that should be enough to navigate by. Actually, I would rather do a little “robot proofing” around the house (covering sensor “holes”) and work with a nice simple byte. Also, I am still working with the idea of using the numbers from the farthest ring that has a wide enough path.

Bits and pieces (of code)

I just attached code to my RuBo (https://www.robotshop.com/letsmakerobots/node/14115). There’s some bit shifting and toggling in player-v*.bas files at least. I used bit packing to store/read beats to/from EPPROM and also to store state information (at least in player-v2.bas; search the code for PL_STATE_ string).

Here’s some bit shifting, toggling, setting and clearing code you can try in Pixace’s simulator. It’s getting really late so I’m not so sure I got right. Hope it helps :slight_smile:

w0 = %1100110010101010 ’ Some test bits
symbol SOME_1_BIT_VALUE_MASK = %0000000000000001 ’ bit 0
symbol SOME_3_BIT_VALUE_MASK = %0000000000001110 ’ bits 1, 2 and 3
symbol ANOTHER_1_BIT_MASK = %0000000000010000 ’ bit 4
’ Toggle a bit
w0 = w0 ^ SOME_1_BIT_VALUE_MASK ’ bit 0 of w0 is set after this
’ Toggle it again
w0 = w0 ^ SOME_1_BIT_VALUE_MASK ’ bit 0 of w0 is cleared after this

’ Set a bit
w0 = w0 | SOME_1_BIT_VALUE_MASK ’ bit 0 of w0 is set after this
’ Set it again
w0 = w0 | SOME_1_BIT_VALUE_MASK ’ bit 0 of w0 is still set after this

’ Clear a bit
w0 = w0 andnot SOME_1_BIT_VALUE_MASK ’ bit 0 of w0 is cleared after this
’ Clear it again
w0 = w0 andnot SOME_1_BIT_VALUE_MASK ’ bit 0 of w0 is still cleared after this

’ Read 3 bit value from w0
b2 = w0 & SOME_3_BIT_VALUE_MASK ’ Now b2 has bits 1, 2 and 3
’ and shift b2 bits to “correct” position (to bits 0, 1 and 3)
b2 = b2 >> 1 ’ Now b2 has “correct” value (5)

’ Set a new value to that "3 bit value"
b2 = 2 ’ We want to store this value (max value = 7)
’ Shift bits to “corrent” position (to bits 1, 2 and 3)
b2 = b2 << 1
’ Clear previous value
w0 = w0 andnot SOME_3_BIT_VALUE_MASK ’ bits 1, 2 and 3 of w0 are cleared
’ Set new value
w0 = w0 | b2

’ Let’s check that we got it right
b2 = 0 ’ Just to make sure we aren’t cheating :slight_smile:
’ Read 3 bit value from w0
b2 = w0 & SOME_3_BIT_VALUE_MASK ’ Now b2 has bits 1, 2 and 3
’ and shift b2 bits to “correct” position (to bits 0, 1 and 3)
b2 = b2 >> 1 ’ Now b2 has the value set earlier (2)

’ Let’s toggle another bit just for fun
w0 = w0 ^ ANOTHER_1_BIT_MASK

’ If the ANOTHER_1_BIT_MASK is set then … else …
b2 = w0 & ANOTHER_1_BIT_MASK
if b2 > 0 then
’ ANOTHER_1_BIT_MASK was set
sertxd (“ANOTHER_1_BIT_MASK was set”, cr,lf)
else
’ ANOTHER_1_BIT_MASK was clear
sertxd (“ANOTHER_1_BIT_MASK was clear”, cr,lf)
endif

’ Let’s toggle another bit again
w0 = w0 ^ ANOTHER_1_BIT_MASK

’ If the ANOTHER_1_BIT_MASK is set then … else …
b2 = w0 & ANOTHER_1_BIT_MASK
if b2 > 0 then
’ ANOTHER_1_BIT_MASK was set
sertxd (“ANOTHER_1_BIT_MASK was set”, cr,lf)
else
’ ANOTHER_1_BIT_MASK was clear
sertxd (“ANOTHER_1_BIT_MASK was clear”, cr,lf)
endif

You could always use some

You could always use some bit trickery to condense your 16 bits down to 8, that way you can control the compression method, rather than just hoping that the lack of resolution doesn’t cause you any trouble =)

If we take the 16 original bits coming from the sensors:
Left Map [l7, l6, l5, l4, l3, l2, l1, l0] where bit l7 is on the far left
Right Map [r7, r6, r5, r4, r3, r2, r1, r0] where bit r0 is on the far right
We can condense them into a new byte, using a couple of different methods:

• Cautious Map [l7&l6, l5&l4, l3&l2, l1&l0, r7&r6, r5&r4, r3&r2, r1&r0]
Using the AND/& operator means that both adjacent bits have to be safe/‘1’ for the corresponding new bit to also be 1. In other words, Walter will flag that area as unsafe if he detects anything in that 8th of his view.

• Reckless Map [l7|l6, l5|l4, l3|l2, l1|l0, r7|r6, r5|r4, r3|r2, r1|r0]
This time the OR/| operator is used, so if at least one bit in that area of Walter’s view is safe, then Walter will determine that the entire 8th of the view is safe.

Now, you might think that there would only ever be reason to use the Cautious Map, but the Reckless Map may be useful for determining possible paths from further away. Or maybe if Walter can’t find any paths using the Cautious Map he’ll get impatient and move towards potential paths as dictated by the Reckless Map for a closer look, just in case they turn out to be wider than they seemed from a distance.