I want to have an ultrasonic sensor pan to make several readings. Then I want the robot car to choose the direction that is furthest from any obstacle that it detects. I think I need some kind of memory or queue. I have not found a “ready-made” node library that provides this kind of short term storage (I don’t yet have an SD card reader).
I came up with the following. This is just proof of concept. For now, I am just trying to persist data ready for output to other nodes. In the following node, I set up a counter which increments each time the ultrasonic sensor (us-sensor) pulses “done”. If that count is less than 5, then I route the distance value from the us-sensor to an ADD node which simply adds 0 to the distance value and then outputs that value. When the count exceeds 5, then the center add sequence stores the value. When the count exceeds 10, the third distance value is stored in the rightmost sequence. When the count exceeds 15, the counter is reset.
The idea is that I would pan during these intervals to get different distance readings. When done, I would make the decision on which way to turn.
My proposed solution (which does work as described) is below. My question is, “is there a better way to do what I want to do?”
For short-term storage, your pass-if/add nodes can be replaced by buffer nodes.
You will need to figure out which buffer to send the Done pulse to; gate nodes could be used to help with that.
The patch has no output to indicate when it has completed a cycle. Looking at the output before it has completed its 1st cycle will result in 0 values for outputs that have not been calculated yet. There is also no input to indicate when it should start or a way to change the angle of the sensor between each reading.
Why do you calculate the range 5 times and only store the last time?
The ultrasonic range finder needs time to settle down between pings. Once every second might be cutting it close. With this setup, it will take 15 seconds to complete a loop. If your robot is moving, 15 seconds is a long time to be moving between checks to see if you will hit anything. You will either need to be moving very slowly, or use a pretty long distance to indicate robot should stop to avoid hitting anything. I assume your long-term plan is to use OUT1 as distance to object to the left, OUT2 distance in center, and OUT3 distance to the right. If robot is moving during these calculations, at least one of those readings is from at 5-10 seconds ago and could be very different now. With your current code, angle would need to be calculated from count if you want OUT* to represent a specific direction.
Why not write your patch to accept a start pulse, which positions the sensor (you will need a delay here so servo has time to move to new position before sensor sends ping), then tells the built-in ultrasonic sensor node to ping, and feed the output to one of your output pins, then route pulse to position sensor to new position and tell another copy of the sensor node to ping and feed that output to another pin, etc., then send pulse to a done pin for the patch. Each copy of the ultrasonic node will keep its value until it receives another pulse to update. Note that any of the ultrasonic nodes might send an error pulse instead of a done pulse; your code will need to process that so the pulse controlling your program flow doesn’t get lost and leave your program hung.
Do you intend to turn your robot even if you are not about to hit anything? If not, you really don’t care about distance to side until you are about to hit something, at which point you could stop your robot and check distance to each side. This would make your robot much more responsive since you don’t have to wait for servo to re-position and extra pings while you are moving forward (which might result in hitting an object before you see it in front of you).
Ok. I was not aware of the buffer node. That is what I was looking for when I did searches for “memory” and “storage”. I’ll definitely use those.
I was just trying to see (via the watch nodes) if I could “store” a value while other values were changing (and stored). I figured I would get to the start-up and out-put later. I’ll add “DONE” pulses and probably use your “combine done pulses” patch to join them into a single DONE output.
That was to give me time to physically move the robot so I would get different readings from the us-sensor! Ok, so this is really primitive!
Yes! I agree. No real point in searching the area if I can safely move forward.
I was hoping that eventually I could speed up the readings.
I thought since I have only one us-sensor on the car, I needed handle all of the readings/outputs with a single XOD us-sensor node in my patch. If I understand what you are suggesting, I’ll have to see if I can put multiple XOD us-sensor nodes on a patch without conflict (all of them accessing the single us-sensor on the car).
Yes. For the moment I am burying my head in the sand regarding errors. Eventually I will need to deal with them. First things first!!
Yes, the loop time is unacceptable. What I would really like to do is implement a feature that some of the us-sensors have (I think mine does) that will actually ping 5 times and report the average distance. But, I do not yet know how to implement that with my us-sensor.
Thanks for the very helpful observations. I will start work on prototype version 2 ( or should I say v0.2).
You should be ok having multiple ultrasonic nodes for one sensor, as long as only one at a time is trying to ping. It will be a mess of multiple nodes try to ping at the same time. The delay needed between pings shouldn’t be much of an issue since servo will need time to move to new position between pings anyway.