"Rocket" Style Locomotive – step 0031 – February 2010
The prototype SrrA1plus2 is a so-called “specific vehicle prototype”. I.e., it takes parameters from the user (vehicle model) and orchestrates them to instrument a functioning SrrTrains vehicle model.
To achieve this goal, it makes use of the generic vehicle prototype SrrVehicle.x3d, that is used for all SrrTrains vehicles.
The user provides four SrrAxle nodes and two SrrTransformationA nodes (the axles containing four further SrrTransformationA nodes in turn). The user must not initialize those nodes.
The user may provide a floating point control node to impose a dozing force. The user must not initialize that node.
The user may provide one or more vehicle drives (a locomotive will usually have at least one drive) to drive the vehicle.
The user may provide one or more vehicle cabs containing controls to provide user interactivity.
SrrA1plus2 will coordinate the initialization of all contained nodes.
SrrA1plus2 supports three modes of operation:
standalone:
The end user has opened the file of the vehicle model directly, without any relation to an SrrTrains layout. The model will stand still, but the wheels will rotate with constant velocity.
static:
The vehicle is embedded into an SrrTrains module as a static model. The module author is responsible for any animation, the wheels will rotate with a constant velocity set by the module.
dynamic:
The vehicle has been registered at an SrrTrains layout, an instance of a vehicle has been created at a setup point and now the vehicle is moving along the tracks.
SrrA1plus2 is an external prototype that is available at the directory srr/.
<ProtoDeclare name='SrrA1plus2'>
<ProtoInterface>
<field accessType='inputOutput' name='objType' type='SFString' value='SrrA1plus2'/>
<field accessType='inputOutput' name='version' type='SFFloat' value='0.0031'/>
<field accessType='inputOutput' name='objId' type='SFString'/>
<field accessType='inputOutput' name='quasiModule' type='SFString'/>
<field accessType='inputOutput' name='mass' type='SFFloat' value="4000"/>
<field accessType='inputOutput' name='wee' type='SFFloat' value="0.0025"/>
<field accessType='inputOutput' name='length' type='SFFloat' value="9.5"/>
<field accessType='inputOutput' name='axlesPositions' type='MFFloat' value='1.0 4.0'/>
<field accessType='inputOutput' name='axle0' type='SFNode'/>
<field accessType='inputOutput' name='axle1' type='SFNode'/>
<field accessType='inputOutput' name='tenderPosition' type='SFFloat' value='5.0'/>
<field accessType='inputOutput' name='tenderAxlesPositions' type='MFFloat' value='1.0 2.5'/>
<field accessType='inputOutput' name='tenderAxle0' type='SFNode'/>
<field accessType='inputOutput' name='tenderAxle1' type='SFNode'/>
<field accessType='inputOutput' name='transformationLocomotive' type='SFNode'/>
<field accessType='inputOutput' name='transformationTender' type='SFNode'/>
<field accessType='inputOutput' name='cabs' type='MFNode'/>
<field accessType='inputOutput' name='drives' type='MFNode'/>
<field accessType='inputOutput' name='parameterLinkage' type='MFString'/>
<field accessType='inputOutput' name='vIdleRotation' type='SFFloat' value="1.0"/>
<field accessType='inputOutput' name='idleRotate' type='SFBool' value="false"/>
<field accessType='inputOutput' name='dozeControl' type='SFNode'/>
<field accessType='inputOutput' name='standalone' type='SFBool' value='true'/>
<field accessType='inputOutput' name='visible' type='SFInt32'/>
<field accessType='outputOnly' name='basicallyInitialized' type='SFNode'/>
<field accessType='inputOutput' name='modParam' type='SFNode'/>
<field accessType='outputOnly' name='initialized' type='SFNode'/>
<field accessType='inputOutput' name='enabled' type='SFBool' value='true'/>
<field accessType='outputOnly' name='staticModel' type='SFBool'/>
<field accessType='inputOutput' name='exitViewpoint' type='SFNode'/>
<field accessType='inputOnly' name='deleteTrain' type='SFTime'/>
</ProtoInterface>
The fields objId, standalone, modParam, quasiModule, initialized and enabled should be directly connected to the model's miMod(Model) interface, maybe doing some intermediate trace output in a script.
The fields mass, wee, length, axlesPositions, tenderPosition, and tenderAxlesPositions set the parameters of the locomotive for the train kinematics. mass is the mass in kg, wee is indicating the friction, length is the “length over buffers”, axlesPositions[0] is the distance of the first axle from the vehicle front (buffer) and axlesPositions[1] is the distance of the second axle from the vehicle front (buffer). tenderPosition is the distance of the front of the tender from the front of the vehicle, tenderAxlesPositions[0] is the distance of the first axle from the tender front and tenderAxlesPositions[1] is the distance of the second axle from the tender front.
axle0, axle1, tenderAxle0 and tenderAxle1 are SrrAxle nodes representing the axles. Each of them must contain an SrrTransformationA node to transport the information about axles's transformations from the track geometry to the vehicle model.
transformationLocomotive is an SrrTransformationA node, whose content will be calculated dependent on the axles's transformations. The vehicle model must use this node to set position and orientation of the whole locomotive.
transformationTender is an SrrTransformationA node, whose content will be calculated dependent on the axles's transformations. The vehicle model must use this node to set position and orientation of the whole tender.
cabs may contain one or more cab objects, drives may contain one ore more drive objects. The parameters of the drives and cabs need to be linked by the parameterLinkage parameter (see the example locomotive for further details).
vIdleRotation and idleRotate are used as input for the idle rotation of the wheels in case of standalone and static operation modes. In case of standalone, the flag idleRotate is ignored and the wheels rotate anyway with vIdelRotation, in case of static, the rotation takes only place, when idleRotate is set to true.
dozeControl is an optional parameter, that may be used to instrument input from the end user. dozeControl will impose a “dozing force” in kg.m/sec^2.
The model should listen to the visible field of SrrA1plus2. Visible outputs either -1 or 0, to be directly used as whichChoice of a <Switch> node.
The fields basicallyInitialized and staticModel output some additional information, which could be useful for the model author. The basic initialization is done, when the vehicle is loaded, before the modParam value can be processed. A standalone model is only basically initialized, but not initialized.
The exitViewpoint is a reference, that can be set by the module author.
If the end user (his avatar) had entered a vehicle, the moving viewpoint of this vehicle was bound. Then the vehicle moved around the layout, could even change modules, and now, when the end user/avatar wants to leave the vehicle, it's the question, which viewpoint should be bound.
The concept of the exit viewpoint allows the module author, to assign a viewpoint to each track section. When the first axle of a vehicle moves into a track section, it will take its exit viewpoint as the own exit viewpoint and report this reference to the vehicle model. Now the model can detect, that the avatar is leaving and can bind this viewpoint.
With deleteTrain the model can request deletion of the whole train. E.g. take the value from the touchTime field of a <TouchSensor> node.