5 junio 2011

Función Speedcurve en Rocrail

Category: Rocrail — Manolo @ 22:04
Este fin de semana he mandado a la gente de Rocrail una contribución para añadir una funcionalidad a Rocrail. Se trata de la capacidad de tener una curva de velocidad que se gestiona desde el ordenador.
La documentación está en Inglés:

Finally I have had some time to implement the functionality I was requesting. I am attaching an explanation on what the motivation was, and how it can be used.
Since I am not at all an expert on C, neither on the rocrail code, it has taken me longer than expected. Moreover, there is still a problem with the code – a memory leak – I have not been able to solve. I think it is in the way I am attaching the speedcurve parameters to the loc command (loc.c file)… but I am not sure – any help, correction and suggestion for improvement is very welcome.
Basically I have modified the wrapper description file to include a new property to the loc (speedcurve). Then I have modified the loc.c file to explore if a locomotive has this property and include them in the commands sent to the stations. Finally, in DDX, this parameter is treated in MM locomotives.
The reason to address only MM is basically because DCC decoders use to have an actual speedcurve functionality. In any case, since the information is transmitted to any station, anyone could make use of it to implement the speedcurve as I have made for DDX MM.
Hope this new feature to be of interest. It needs still some refinement for the memory leak.. but hopefully someone could give me a hint on how to solve it, so it can be included in a stable release – if it is of interest of course.
I am attaching the three source code files modified, a plan example and the explanation of the functionality.

Description and motivation

A speed curve is a well-known feature of new decoders, and especially it is a feature extensively used in DCC hardware. The solution is normally based on a number of CV that grants the user with the possibility to specify non-linear speed curves, which are closer to reality. The speed can be set per engine step and in addition it is also possible to define the acceleration and deceleration time.
Older decoders, and especially some low-cost solutions designed to work with the motorola format, cannot access such rich feature. In the best scenario it is possible to adjust the acceleration and deceleration time, but never to define different parameters per engine step. This handicap can be easily overcome by software with Rocrail, introducing predefined speed profiles per engine step that can be interpreted by DDX.
The speed curves by software, or speed profiles, are based in the definition of the time each step needs to be hold before going to the next/previous one. It is noteworthy to clarify that the functionality provided by a hardware speed curve is not exactly the same, since a speed profile will not affect the speed magnitude, but the acceleration/deceleration time between steps.
In this way, it is easy to code curves forcing long pauses to accelerate for the lower steps and short pauses for the higher steps, or long pauses to decelerate in higher steps and low pauses in the lower steps.
ACCELERATION CURVE 1
DECELERATION CURVE 1
Furthermore, speed profiles have been proved especially useful in some decoders that, in addition to the lack of a speed curve, have some particular time constraints to achieve an efficient behavior:
  • Märklin DIGITAL 146871 PIC-Decoder 1. This low-cost decoder needs some pause after any speed change request to actually reach the new speed. This is important when two consecutive commands are sent, and especially critical if a change of direction is requested. In those cases, the decoder needs to stop before implementing the change of direction. Without the mandatory pause, the engine does not «accept» the request, and the change of direction is never achieved.
  • TAMS LD_W_3. This decoder needs an update on the speed after a change of direction request. Otherwise, the delay in accepting the order depends on the loco stack of commands and active protocols in DDX – worst scenario up to 18 seconds of delay with MM, MMLP and DCC active.
  • Motorola format I. This protocol forces a stop whenever a change of direction is requested. The behavior can be improved by implementing speed profiles, which may help considering the speed when
    the change of direction is requested as a persistent variable. In this way, after the change of direction is implemented, the speed is recovered and the loco does not stop.

How it works

The speed profiles are implemented as a new feature for DDX working on Motorola protocol locomotives. The user needs to define per each step (14 or 28 steps) the delay until the next or previous step. As an example, the accelerating curve in previous section is defined by:
Step
Delay to next step (ms)
Next step
0
1500
1
1
1000
2
2
900
3
3
800
4
4
700
5
5
600
6
6
500
7
7
400
8
8
300
9
9
200
10
10
200
11
11
175
12
12
150
13
13
125
14
14
100
NA
The curve can be extended to 28 steps. In any case, as expected, the last parameter – i.e. ms to go beyond the maximum step – is never used.
IMPORTANT: a minimum delay of 10ms between steps should be respected (100ms recommended value). Otherwise, depending on the platform, the rocrail serveray collapse.
In a similar way, the deceleration file is defined by:
Step
Delay to previous step (ms)
Next step
14
2000
13
13
1800
12
12
1200
11
11
1000
10
10
600
9
9
600
8
8
500
7
7
400
6
6
300
5
5
200
4
4
175
3
3
150
2
2
125
1
1
100
0
0
200
*Pause before sending a refresh in a
change direction request
In this case, the last parameter, which was not used in the speed profile definition, has been used to code a pause if a refresh message wants to be sent at the end of the sequence when a change direction is requested – 0ms =non refresh.
In reaction to a speed change request, a sequence is initiated to reach the new speed going through the curve. In this way going from v=4 to v=9 would trigger the following sequence:
· Wait 700 ms and V=5
· Wait 600 ms and V=6
· Wait 500 ms and V=7
· Wait 400 ms and V=8
· Wait 300 ms and V=9
In the same way a change of direction in v=4 would trigger the following sequence:
· Wait 175 ms and V=3 reverse
· Wait 150 ms and V=2
· Wait 125 ms and V=1
· Wait 100 ms and V=0
· Wait 1500 ms and V=1 forward
· Wait 1000 ms and V=2
· Wait 900 ms and V=3
· Wait 800 ms and V=4
In the case of having any delay defined for v=0 – for instance 200ms-, at the decelerating curve, a last message would be sent:
· Wait 200 ms and V=4
The decelerating curve would be used in a similar way to go from v=9 to v=4.

Configuration

The configuration of any speed profile is done at the XML file describing the layout.
As a new parameter describing a loco, now it is possible to include a «speedcurvestep»:
<lc id=»130TB SNCF» mtime=»0″ prev_id=»130TB SNCF» shortid=»130TB» roadname=»former Royal Prussian State Railways (K.P.E.V.) class T 12.» number=»130TB» desc=»» docu=»» image=»tb130.png» imagenr=»0″ remark=»» len=»12″ nrcars=»0″ catnr=»36742″ purchased=»2010″ identifier=»0″ show=»true» useshortid=»false» mint=»40″ bus=»0″ addr=»78″ iid=»» prot=»M» protver=»2″ spcnt=»14″ fncnt=»2″ V_min=»10″ V_mid=»50″ V_max=»100″ V_Rmin=»0″ V_Rmid=»0″ V_Rmax=»0″ V_step=»0″ mass=»0″ V_mode=»percent» placing=»true» regulated=»true» restorefx=»true» dirpause=»0″ blockwaittime=»10″ evttimer=»0″ ent2incorr=»100″ priority=»10″ usescheduletime=»false» commuter=»false» trysamedir=»false» tryoppositedir=»false» forcesamedir=»false» shortin=»false» inatpre2in=»false» usemanualroutes=»false» engine=»steam» cargo=»mixed» secondnextblock=»false» consist_lightsoff=»false» consist=»» V=»0″ throttleid=»» fn=»true» fx=»0″ runtime=»33775″ dir=»true» mode=»» resumeauto=»false» active=»true» scidx=»-1″ server=»infw01EFE784″ dectype=»» blockenterside=»true» throttlenr=»0″ manual=»false» swaptimer=»0″ useownwaittime=»false» startupscid=»»>
<fundef fn=»4″ text=»» timer=»0″/>
<fundef fn=»0″ text=»Luces» timer=»0″/>
<speedcurvestep step=»0″ nsleep=»3000″ psleep=»0″/>
<speedcurvestep step=»1″ nsleep=»0″ psleep=»1500″/>
<speedcurvestep step=»2″ nsleep=»0″ psleep=»1000″/>
<speedcurvestep step=»3″ nsleep=»0″ psleep=»2000″/>
<speedcurvestep step=»4″ nsleep=»0″ psleep=»100″/>
<speedcurvestep step=»5″ nsleep=»0″ psleep=»100″/>
<speedcurvestep step=»6″ nsleep=»0″ psleep=»500″/>
<speedcurvestep step=»7″ nsleep=»0″ psleep=»100″/>
<speedcurvestep step=»8″ nsleep=»0″ psleep=»500″/>
<speedcurvestep step=»9″ nsleep=»0″ psleep=»300″/>
<speedcurvestep step=»10″ nsleep=»0″ psleep=»500″/>
<speedcurvestep step=»11″ nsleep=»0″ psleep=»300″/>
<speedcurvestep step=»12″ nsleep=»0″ psleep=»200″/>
<speedcurvestep step=»13″ nsleep=»0″ psleep=»200″/>
<speedcurvestep step=»14″ nsleep=»0″ psleep=»100″/>
</lc>
For each step the ms to wait until the next and previous steps need to be set.
If a step is not defined, or if it is defined with a 0ms wait, it will not be considered in the acceleration, or deceleration profile. Thus, a speedprofile as the one above will produce the following curve:
ACCELERATION CURVE 2 (wait in v=0 3000 ms)
DECELERATION CURVE 2
The sequences presented(v=4 to V=9) before would become:
· Wait 0 ms and V=9
Delays equal to zero are not considered.
And V=4 change direction would become:
· Wait 100 ms and V=3 forward
· Wait 2000ms and V=2 forward
· Wait 1000 ms and V=1 forward
· Wait 1500 ms and V=0 forward
· Wait 3000ms and v=4 reverse

Examples

The attached file (speedr) presents the modified source files and four examples :
· One typical speed profile (curve 1, Firemen)
· One low cost (curve 2, 130TB)
· One motorola I (curve 3, BR44)
· One tams (curve 4, V160)
The rest of the locomotives are just included to test that the speedcurve does not affect other decoders.
ACCELERATION CURVE 3(no delay)
DECELERATION CURVE 3
ACCELERATION CURVE 4 (no delay)
DECELERATION CURVE 4 (repeat chdir)

Sin comentarios »

Sin comentarios.

RSS feed for comments on this post. | TrackBack URI

Deje un comentario

XHTML ( Puedes usar las siguientes tags):
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> .