Mikko Rasa [Wed, 7 May 2014 20:26:13 +0000 (23:26 +0300)]
Avoid segfault if an exception is thrown while loading
The Layout::add functions are called from object constructors. If an
exception is thrown inside them, the constructor will abort and the
object will be deleted. If that happens, it must be removed from the
Layout as well, or an invalid memory access will occur later.
Mikko Rasa [Sat, 3 May 2014 09:17:07 +0000 (12:17 +0300)]
Fix a bug with attaching ends in ExtendTool
This managed to avoid a segfault despite the null pointer dereference,
because the first thing Track::link_to does is check if the passed-in
reference is a track, and a null pointer isn't.
Mikko Rasa [Sat, 3 May 2014 09:15:22 +0000 (12:15 +0300)]
Move gauge to TrackAppearance
It may eventually be desirable to have multiple gauges in the same layout
(narrow-gauge trams together with a standard-gauge railway, for example),
and this is a necessary step towards that.
Mikko Rasa [Mon, 14 Apr 2014 06:00:30 +0000 (09:00 +0300)]
Simplify sequence handling
Instead of checking all sequence points when another train reserves a
block, only check the first one. The subsequent ones can be checked
when they become relevant.
Mikko Rasa [Fri, 11 Apr 2014 19:12:39 +0000 (22:12 +0300)]
Use a better cost estimator for the route planner
Total time is not good because it doesn't penalize waiting time for
earlier trains. This can cause the state tree to explode as later ones
start moving.
The sum of travel and wait times for each train works much better.
Mikko Rasa [Fri, 11 Apr 2014 18:18:09 +0000 (21:18 +0300)]
Fix lead route generation
Lead routes are now created up to the target, but not past it. This fixes
a problem where a route diverging from the train's reserved blocks caused
the router to attempt to create a lead route with gaps.
Mikko Rasa [Thu, 10 Apr 2014 19:04:03 +0000 (22:04 +0300)]
Use path coercion in track iterators
This enforces common traversal rules in all places. It also fixes a bug
in TrackOffsetIter where moving to a turnout from an endpoint not on the
selected path would potentially cause an out-of-range iterator to be
created.
Mikko Rasa [Sun, 6 Apr 2014 20:28:53 +0000 (23:28 +0300)]
Don't set pure_speed and accurate_position when halted
It may happen that the train has enough momentum to roll onto the next
sensor when halt occurs. Setting accurate_position in this case is
likely to cause a sensor missed emergency when halt is lifted, as the
physical locomotive takes a moment to get up to speed again.
Mikko Rasa [Sun, 6 Apr 2014 20:08:32 +0000 (23:08 +0300)]
Fix handling of uncertain bits in accessories
When the state of an accessory is first set, send commands for all
uncertain bits. Otherwise the accessory could remain unsynced or a
failure could go undetected.
Always clear the uncertain bit after setting an accessory, not only
when it failed.
Mikko Rasa [Wed, 2 Apr 2014 20:12:55 +0000 (23:12 +0300)]
Improve tool status display
If a tool finishes instantly and displays a status (such as SlopeTool
or ExtendTool when they encounter an error during construction), do not
replace it with the selection tool status.
Mikko Rasa [Tue, 1 Apr 2014 18:35:31 +0000 (21:35 +0300)]
Use current monitoring to detect failed turnouts
The turnout solenoid takes quite a bit of current, which is easy to
detect. If there's no current spike after activating a solenoid, it
may have a broken microswitch that prevents operation.
Mikko Rasa [Tue, 1 Apr 2014 18:14:35 +0000 (21:14 +0300)]
Keep track of the active accessory bit index
Failing to do this may theoretically cause trouble if a multi-bit
accessory spans a k83 module boundary. Sending a deactivation command
for the first bit would only turn off the first module but not the
second.
Mikko Rasa [Sun, 30 Mar 2014 17:22:31 +0000 (20:22 +0300)]
Add a distance metric to turn the routing into an A* search
The original straightforward implementation exploded in complexity much
sooner than I expected. The reasons are not entirely clear, but the
inability to converge states and drop those where the same position was
already reached through a faster path may have something to do with it.
Mikko Rasa [Sun, 30 Mar 2014 16:36:47 +0000 (19:36 +0300)]
Check that occupied_track is not null before accessing it
This could only happen if an exception is thrown from TrainRoutingState
constructor, but the resulting segfault can act as a red herring and
distract from the actual cause.