Skip to content

Conversation

@gfgit
Copy link
Contributor

@gfgit gfgit commented Sep 18, 2024

Super ugly code just as proof of concept.

Now that #163 is quite working, I'm exploring new possibilities.
Knowing locomotives speed curves, (maybe combined together in a Train), we can now how much distance the Train has traveled.

Precision depends on how accurate is the speed curve file which gets imported for each locomotive.
I did some quick measures, without spending much time so accuracy could be improved a lot, and yet the result is already good.
In this small example:

  • Take a locomotive with decoder set and speed curve loaded
  • Put it alone in a new Train (so it uses raw curve data, since matching could introduce some rounding)
  • Activate Train
  • When you activate locomotive function F1 (then you can deactivate) Traintastic starts to track that Train until it travels for 20 centimeters (0.2 meters)
  • You can make locomotive go as fast as you like, even stop it and restart (but not yet change direction)
  • When Traintastic estimates traveled distance is >= 20 cm, locomotive F2 is enabled to tell you of the result.
  • Tracking is deactivated until you (disable and) re-enable F1

From my tests the average error is of 2 centimeters which is quite acceptable for our purposes.

With this functionality we can for example:

  • Release BlockPath when Train enters exit block and travels it's own length plus a safe margin, and of course once entrance block is freed.

  • Make some automation based on position but without position sensors (like infrared or magnet) and at a finer precision that block sensors.

  • Example play horn just before a level crossing or when entering/exiting a tunnel

  • Play horn when crossing another Train on opposite track

  • It's also useful to better control Train speed in future Automatic mode based on position, like start to brake only after 10 cm from yellow signal for whatever reason.

  • Should tracker be an object which subscribes to a Train and then removes itself when reaching it's target?

  • Multiple trackers could be active at same time for same Train

  • Maybe we could use boost signals on properties but overhead should be kept to a minimum to keep time precision.

gfgit and others added 30 commits September 12, 2024 11:53
- Connect to decoder changes
- Remember last speed set by train
- Do not change train speed in response to train changing
  decoder throttle to avoid infinite recursion
TrainVehicleList now stores train-specific settings

- Swithced TrainVehicleList to ObjectVectorProperty
  instead of deriving ObjectList

- TrainVehicleListTableModel: new custom TableModel for TrainVehicleList

- RailVehicle reference to Train now is managed in addObject() and removeObject()
- Use destroying() to disconnect signals
- Make a final class

'boost::signal2::connection' does not automatically disconnect
on destruction.

This was causing crash because RailVehicle is deleted after
TrainVehicleListItem so it would call the lambda with dangling pointer
to an already deleted TrainVehicleListItem
- Correctly set inverted direction
- Sync all vehicles direction when activated
Do not propagate PoweredRailVehicle direction back
to Train if the change was caused by Train itself.
This saves 2 calls and an array lookup to check if
vehicle is inverted.
- Stop forcing throttle to rounded values when propagating
  train speed
- Do not add vehicle to an active train if it is already
  in an other active train

- When removing vehicle from active train reset
  activeTrain property

- When adding vehicle to active train, set it's activeTrain
  property
This makes loading more robust against file
corruption or invalid states.
The property is now set in Train::loaded()
or whole Train activation is discarded.
- PoweredRailVehicle: added VehicleSpeedCurve
- Revert to old step when exceeding max
- Train: stopDelayedSpeedApply() on emergency stop
- Remove old code
- This prevents it getting stuck if cannot reach next match in one go
@reinder
Copy link
Member

reinder commented Sep 18, 2024

Awesome 😎, need to check the code, but I really like it.

What will help I think to improve the accuracy is time stamping the input changes in the kernels, and send it with the change event, then we can eliminate the event loop delay. I can look into that.

I'll put this one on draft for now, we can then remove draft status once we are finalizing the last bits of a PR. (So I can easily see which ones I need to prioritize.)

@reinder reinder marked this pull request as draft September 18, 2024 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants