Procedure running once when conditions for running remain the same

I have done my best (heh) to reduce the blocks only to those I am talking about.

The Goal: When I arrive at a location, TTS the name of the location, and the next stop.

The problem: I can make the app do as I want initially, but as the vehicle slows to a stop at each location the criteria set for the TTS are met several times and the TTS overwrites itself until the bus is no longer in motion. I have used a timer to check conditions. Getting the procedure to only run ONCE when conditions are first tested TRUE is testing my sanity.

Tried solutions:

Setting TRUE/FALSE variable: Variable is initialized as FALSE. When location is within a defined area on the map, set variable to TRUE. If TRUE, TTS procedure runs. After TTS procedure runs, variable is set to FALSE. However, because the vehicle is still at the location, it turns the variable TRUE and I am stuck in a loop of screaming 'NEXT STOPS".

The same applies if I attempt to do a distance variable. Its always in that distance so it screams at me.


LoopHelp.aia (102.3 KB)

Your atStop Procedure is probably doomed to failure. I think you specify a specific latitude/longitude the LocationSensor needs to exactly match a location in a database. An exact match of coordinates seldom happens. Why?

  • the LocationSensor does not really know where it is with any precision. Read about the Property called Accuracy to clarify this phenomenon. Using the Location Sensor explains the issue of uncertain, imprecise information. Unsure? Do the two tutorial examples - just load the aia’s to your device and experiment. A LocationSensor, resting on a desk, reports locations for the device GPS_Accuracy_Logger ; note that no two readings are the same.

Graphically, this looks something like this RingFence2

  • If the device is moving rapidly, the device will probably blow through the specific geocoordinates between satellite fixes.
  • if you sample coordinates more often than 30000 ms (every 30 seconds) you do not give the gps receiver an opportunity to achieve a new satellite fix (and report a new, perhaps ambiguous, location.

What you can do?

  • use a ringed fence to determine you are there. See Location sensor (ringed fence / circular ringed fence)
  • or continuously calculate the straight line distance from the device to the geocoordinates and when the distance gets close; decide you are there. Remember, most devices cannot resolve small distance changes with any reliability at all and not rapidly.
  • a few years ago, a developer wrote a program to determine whether someone arrived or was arriving at a specific bus stop. I think it was called HalteAlarm, he used a different technique by using (from LocationSensor ) … DistanceInterval ---- Determines the minimum distance interval, in meters, that the sensor will try to use for sending out location updates. For example, if this is set to 50, then the sensor will fire a LocationChanged event only after 50 meters have been traversed. However, the sensor does not guarantee that an update will be received at exactly the distance interval. It may take more than 5 meters to fire an event, for instance. It is also useful to check against Accuracy when using this property. When your device is moving, the accuracy of the detected location is constantly changing. He sets the DistanceInterval in the LocationSensor to 400 meters and finds this worked well for his purposes.

Think about how you are determining that you have arrived. I suspect you have a problem. Be aware what the gps hardware is capable of doing and you will finish your app. :slight_smile:
Good luck.

Regards,
Steve

1 Like

Could you stop the clock from firing after the first run of the procedure, then allow the clock to fire again once the bus leaves the geofence ?

An extra test is needed to see if the currently detected stop number matches the next stop number.
Here’s a possible fix, draggable blocks…


You should be able to drag it into your blocks editor.

The exact match I assume is coming from the blocks that ask if the distance is zero or less. EDIT: I had changed the test to show the distance (straight line) to the next stop. Sorry.

The radius of the circle is set at a number, say 50 meters, and the centroid is set to false (which if I understand means that it measures from the edge of the circle, not the center point). This gives me about a 100m margin of error. I have been logging stops/pickups with the location sensor for about a year - and seldom do I receive a reading that is out in left field. I have found most of my ‘errors’ in location come from drivers forgetting to to their part at the stop and trying to do it after they have departed the stop.

The thought behind the </= 0 was that if the reading is negative, that they would be ‘inside’ the circle, while a positive reading would mean they were outside. This was an attempt to set a condition to limit the TTS from overwriting itself, but I ended up with issue becuase the at atStop function just overwrote the FALSE variable it set.

In the atStop procedure, the first ‘if’ determines if the reading is within about a 150m rectangle, based on a lat/long difference of 0.00075 in either direction. (My math could be, and probably is wrong). I am also finalizing a orientation check as well (azimuth) to make sure I don’t call a stop that is close but is not the one I need to go to based on azimuth.

This is what I was leaning towards - but I don’t know how to make a timer fire once, and then not again.

Reactivating the timer when the bus reaches a certain speed, or when the distance from the geofence meet a threshold. However, the threshold might be problematic:

Criteria met to make the Timer fires would happen when it approaches and leaves the geofence; which would make it loop again and again… if I am thinking correctly.

Use this block

blocks (32)

As a test, I used the timer to change each button’s color. Button 1 keeps flashing, button 2 only changes once and then stops.

Is this the method you eluded to or is there a simpler way? When I used the TimerAlwaysFires block instead of the TimerEnabled block, button2 just kept flashing ( just keep flashing, just keep flashing)

timerFiresonce.aia (2.7 KB)

What is your expected result with the buttons?
What should happen in which order?

Eh, I see the error of my ways - I am not using timer2 to change the colors, only the button press and with the button press I am turning timer 2 on and off with no effect to my button color.

So again: What should happen in which order?

This is what should have happened. i think. Button1 always flashes, when button2 i pressed, timer2 starts, runs the test, and then turns off; only changing the button color once.

However, this will not stop my original problem, as each time my conditions for atStop are met, the timer will reactivate and then turn off - resulting in the screaming TTS.

Ah, ok I see

Thanks. I also had to add a test for lat/lon =/= 0, otherwise I received an error until the GPS reported a location.

Here are two extensions that may be useful for your purposes:

1 Like