Originally Posted by
Rick19468
Does this method afford self "re-entry" back into the yard (no zapping or beeping)? .... then system must "self reset" to an armed status.
Of course. My example code does not do that, as it's just an example of an one-off test.
To achieve something like that, you need a state machine.
You need to store the dog's status, and a timer or a counter for how long the dog has remained in that status, and then decide what to do based on the three (old status, duration, new status):
Code:
static int8_t state; /* DOG_GONE, DOG_WARN, DOG_SAFE */
static uint16_t duration; /* since last ZAP or WARN */
static uint16_t warning_interval;
static uint16_t zap_interval;
/* The normal operation infinite loop: */
while (1) {
int8_t new_state;
new_state = check_location(...);
if (new_state == DOG_SAFE) {
/* We don't care how long the dog is in the yard, just that it is. */
state = DOG_SAFE;
duration = 0;
} else
if (new_state == DOG_WARN) {
if (state == DOG_SAFE) {
/* Dog moved from safe to warning zone. Beep immediately. */
state = DOG_WARN;
duration = warning_interval;
} else
if (state == DOG_GONE) {
/* Dog returned, has one beep interval to get safe. */
state = DOG_WARN;
duration = 0;
} else {
/* Dog remains in warning zone. */
duration++;
}
/* Time to beep? */
if (duration >= warning_interval) {
duration = 0;
BEEP();
}
} else { /* DOG_GONE */
if (state != DOG_GONE) {
/* Dog just got away. Zap immediately. */
state = DOG_GONE;
duration = zap_interval;
} else {
/* Dog remains out. */
duration++;
}
if (duration >= zap_interval) {
duration = 0;
ZAP();
}
}
/* Fixed-length sleep here, so the counters don't advance too fast. */
}
Note that the duration variable indicates the number of cycles spent in that state, so initializing it to say zap_interval means the ZAP() condition will occur in the same cycle, re-setting the duration to zero. Think of it like a capacitor, charging. If the dog does not return, it will re-ZAP after zap_interval cycles.
The above code is just one example. I'd expect you to design and test the state machine throughly (even using just pen and paper, but checking all possible situations) before implementing it.
Originally Posted by
Rick19468
Does this method afford crossing the outer polygon where needed? (ie: dog is allowed out the front door to roam only the front yard. The polygon is only in the front yard. The house is NOT then in the polygon. One line of the boundary now cuts across the front door!! .... dog gets ZAPPED! ... is your method "maskable" to this area?
Sure. You'd need to create a polygon, say a small rectangle, where the dog is allowed to exit.
This requires a more complex dog state list. Perhaps
- Dog is safe
- Dog is in the warning zone (from safe)
- Dog is in the warning zone (returning from outside)
- Dog is in the exit zone
- Dog is outside without passing exit zone
- Dog is outside but has passed exit zone
Actually, here the circle method might come in very handy -- there is no reason why one could not merge the two approaches. The exit zones could be circular, so the owner just need to "mark" them with one click. (You can set the radius with another click.)
It is also possible to modify the function, of course. Each edge and each vertex can have their own warning distances, for example.
Originally Posted by
Rick19468
This looks like your method requires the homeowner (during set-up) to record his primary yard points (polygon) offseted 3-4ft (warning buffer) from the real intended boundary.This would be unacceptable. The homeowner should have only to think about where the intended boundary line is desired and to walk to that point and "click" (recording that XY).
I did that intentionally: I'd rather have the warning buffer outside the safe area, rather than inside.
To me, the warning means "dog, you're not where you are supposed to be", not "don't go there, dog". Canines live in the moment, and seem to respond better to that sort of warnings.
But no, it is not inherent in my method. It is just an implementation detail I chose.
If you want the warning zone inside the polygon, the function can be adjusted to return 0 outside the polygon. Inside the polygon, considering your new requirements, you could compare the distance to each vertex and edge to a per-vertex or per-edge limit. It's not that big of a change to the function, actually.
(Your requirements do seem to change, as the discussion progresses. If I sound a bit negative, it is because it is a very common problem in software development, which I personally find excruciatingly frustrating. It is one of my many character flaws, sorry. If you can tell me exactly what you'd like to get from the polygon checking function, I think I could edit it to match.. but right now this feels like scattershot guesswork, where my efforts are unlikely to prove useful to anyone in the end.)
The way I thought about the situation is that the owner should walk the area where the dog may stay in peace, without warnings. Then the owner may mark areas that are expressly forbidden, by walking their exact boundaries.
If you have enough memory, you could even store different zones (yard, house), where transitioning is only allowed via certain points.
Have you done any real-life simulations? I mean, talk with other dog owners to see how they'd like to define the zones? How many zones are they likely to need? How accurate are the GPS units you'll use for local measurements?
I believe you're going to find that you'll need to add an EEPROM or flash chip to your device, to give it at least a few kilobytes of data memory to manage all the zone information. Even then you must think of how the state machine will behave if a brown-out occurs (battery power runs out), or a glitch causes the device to reset (clearing the state machine, or jumping it to an invalid state). There are a lot of details to consider and design for. You really should consider the big picture and real-world use cases before delving into the details like point-in-polygon testing, in my opinion.