-
-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Train: new active property #44
Conversation
Maybe we should move active property handler to a member function instead of lambda inside constructor |
Nice summary and checklist :) Train activation runs in the event thread (almost all calls do), they are processed one by one, they don't run parallel. So you can check if activation is possible before setting the p.s.1. |
78205c6
to
f032a8c
Compare
Sorry, not building because I called "bind" in a wrong way. |
No problem, that is what the action is for, to check those things :)
To be able to use The client side throttle widget must be modified too, it can't handle that at the moment because it wasn't used until now. |
I was going for forcing speed to zero and discarding speed changes from clients. The problem I'm having is that The Train is stuck in Accelerating state and updateSpeed is not called from property change so the speed is always zero after train is activated |
Disabled properties don't accept setting a value (unless It would also be nice to use the enable state to inform the user that the throttle is disabled. Sending commands to the server is useless.
Don't know how it is implemented now, but be aware that using |
The point is if I call EDIT: changed handler fixes the issue But it's not working properly yet. "isStopped" property is true even when running. |
The set handler verfies the new value, if it returns true the property value is updated and then the changed handler is fired. I think we should build soms test, that makes it easier to check all situations, the EventLoop needs to run to, that may be a bit tricky. |
|
Squashed 2 commits together, rebased on current master and force pushed |
Hi, how do we avoid infinite loop of Train set speed -> decoder changes speed -> update train speed? |
Strange enough I do not get infinite recursion... |
In
If we need this I suggest to add a About handling other speed changes When using a handheld controller, e.g. WiThrottle or WLANmaus, those commands are now send to the decoder, if we make the decoder aware of the vehicle it is connected to we can easily redirect the commands via the vehicle to the active train. (If the vehicle is in only one train and it isn't active we can even try to activate it....but that won't work in all cases so it might be confusing for the user). Another reason to make the decoder aware of the vehicle is that we currently can assign a decoder to multiple vehicles....not good. What about direction changed? Estop? On my wishlist is also a train mode property, it can be set to:
Maybe we need something like this already. Please share your thought :) Think we need no walk troughs different scenarios to find a solution and maybe add some setting so the user can choose the preferred behavior. |
How do you alter the Decoder? p.s. I posted my message before I read this one. |
I have committed all the changes. I did not touch Client code, only Train and
The only possible reason I can imagine is that by scrolling throttle widget with mouse, multiple speed changes are sent but because server debugger hits a breaking point, it handles only the first (until point 5) and then reads the client queue and goes on (point 6, which is like point 1) |
Scrolling throttle widget with mouse can indeed send multiple messages, I'd expect one per "tick". The decoder throttle was temporary (because Trains didn't have them), so that should be removed. We should also test with an external throttle, e.g. Z21 app via WLANmaus or EngineDriver (Android) / WiThrottle (iOS) via WiThrottle. I'll try to look into it tomorrow further. Real hardware is also tricky as is has a response time and the response is handled async so the boolean guard is the gone already. |
Yes I agree, this was a quick test so I used the signals.
This is correct. Let's say I have 2 locomotives and one of them has slow acceleration (and Traintastic is aware of that somehow), it can make train acceleration slower to avoid temporary speed mismatch while the 2 locomotives accelerate because the faster one reaches the target speed sooner.
I'm not confident on this. It seems not really elegant. Decoder is abstract and I think it can be associated also to a turnout. This is the same recursion loop seen above but it involves different components (not only software this time) so it's even worse because we cannot use the bool guard trick on async communication with the command station.
I've implemented Estop but not direction change yet.
This is very cool. It would allow background automatic traffic while manually driving a train and collisions are avoided by signal system and automatic trains could adjust the route based on manual trains getting in their way. |
About this I would not consider WiThrottle "external" if connected directly to Traintastic. This is different from a real command station which keeps inside an internal record of decoder states, so we cannot cheat on object state because the effective value is decided by the command station. To intercept we can only quickly tell the command station to alter the state of a specific object, differently from what user has just set. |
I had an idea. |
This second approach seems to work but suffers of rounding errors.
Here I have a train with a single powered vehicle with max speed 50 km/h
You can easily see that when user sets a new speed directly from decoder throttle (NOTE 1), it is then reset to original value and follows the acceleration curve but end value is a bit different (NOTE 2) NOTE 3: the decoder is at 128 steps, the first value is step 8.72 (not possible) while final value is exactly step 9 which is correct. |
Acceleration is determined by the train, for smooth operation it is best that the decoder doesn't do any braking/acceleration by itself. If Traintastic has to take that into account to it becomes much harder. Most decoders nowadays have a function to disable those braking/acceleration curves. (And that's why Traintastic has an always on/off option for functions :))
The We need at least something to make sure it isn't possible to "plug" the same decoder in multiple powered vehicles, that will give all kind of weird issues.
For the direction we should test the value against the decoder it is received in, if it matches, do nothing, else toggle the train direction. That will then correct the other powered vehicle directions.
One day we will get there :)
I agree, the WiThrottle etc. is easier to handle because the command station isn't involved yet. So we can do that later :) Their implementation is also a bit different, so that needs to be corrected too.
Mapping it to speeds steps can be tricky:
e.g. LocoNet, see here corrects the throttle without epsilon, that will cause issues. Because of the 126 steps it should use an epsilon based on the, so if the throttle is LocoNet step 9.73 which will be send as 10 then it shouldn't update the throttle value to 10 but keep 9.73 because it is within the bandwidth. If something on LocoNet changes it to 11 the it must update the throttle value to 11 / 126. I bought a 2nd hand LocoNet throttle (FRED) some time ago....didn't try it yet.
Nice analysis and test run, I like it :) I wonder why the is a difference at the end, the train should always correct the value to the target speed for the final step. If the decoder throttle is set by something else than the train, should it not just set the train speed accordingly and bypass the acceleration/braking logic? I think Traintastic then has to asume that something else is "in control" and just accept the speed. (Might change when mode is added in the future) |
Lets say you have vehicle A and B in a train. Then you break the train, run B trough a reverse loop and couple back to A in the same train or a new one. Now B has swapped direction compared to A.
I've added a new |
You not yet pushed it :) I'd like to see what you made :) |
I'm not sure it's the rigth approach. If decoder is set to 128 steps it gets rounded to it but then you send through Loconet which has 126 steps and all gets scaled with loss of precision. |
Modifying values when setting a property can be done in the I think it is best to leave the value untouched as long as it is in the step bandwidth of the interface/decoder. I really need to do some test with a command station and a roller bench this week. |
@gfgit can we split this PR into one for the active train stuff and one for the speed update from Setup my rollerbench with two locomotives, driving a train with two engines works fine. Next step is to experiment with spped/direction changes by throttles on the command station (I use a Digikeijs DR5000 via LocoNet). For that the active train part is needed :) |
It is mirrored in RailVehicle activeTrain property. Activating a Train is an atomic operation: - Every contained vehicle must not be in other active train - It also must be stopped Train: setTrainActive() new function to activate Train
Update RailVehicle "activeTrain"
- Sync emergency stop state when activating a Train
097df20
to
4a6b00c
Compare
It is mirrored in RailVehicle activeTrain property.
Activating a Train should be an atomic operation as it must check for every contained vehicles to be free and then proceed.
See discussion: #26
TODO: