409 lines
14 KiB
JavaScript
409 lines
14 KiB
JavaScript
var throttleSpeed = 0; // The speed of the train
|
|
var throttleForward = true; // The direction of the train
|
|
var locoPos = 100; // The position of the loco
|
|
// var locoPos = 700; // The position of the loco
|
|
// var locoPos = 830; // The position of the loco
|
|
// var locoPos = 982; // The position of the loco
|
|
// var locoPos = 765; // The position of the loco
|
|
// var locoPos = 707; // The position of the loco
|
|
var selectDivergedTrack = false; // Should the train go to crane track instead of harbour track?
|
|
var turnoutThrown = true; // Is the turnout thrown?
|
|
var diveringTrackAngle = 0; // The angle of crane track?
|
|
var turnoutPos = 0; // Where does the diverging track starts?
|
|
var carPos = 0; // Position of the car
|
|
var carIsFilled = false; // Is the car loaded with coal?
|
|
|
|
var craneX = 737; // Crane X position
|
|
var craneY = 540; // Crane Y position
|
|
var craneMinAngle = -160; // Minimum angle of the crane
|
|
var craneMaxAngle = 90; // Maximum angle of the crane
|
|
var craneAngle = craneMinAngle; // Current angle of crane
|
|
// var craneAngle = 59; // Current angle of crane
|
|
var commandedCraneAngle = -1; // Commanded angle of the crane
|
|
//var craneUpDown = -1; // Current crane arm up/down (up = 100, down = 0)
|
|
var craneUpDown = 100; // Current crane arm up/down (up = 100, down = 0)
|
|
var commandedCraneUpDown = 0; // Commanded crane arm up/down (up = 100, down = 0)
|
|
var craneBucketOpenClosed = -1; // Current crane bucket open/closed (open = 0, closed = 100)
|
|
var commandedCraneBucketOpenClosed = 0; // Commanded crane arm up/down (open = 0, closed = 100)
|
|
var craneBucketFilled = false; // Is the crane bucket filled?
|
|
|
|
var sensor1_active = false;
|
|
var sensor1_Pos = 30;
|
|
var sensor2_active = false;
|
|
var sensor2_Pos = 760;
|
|
var sensor3_active = false;
|
|
var sensor3_Pos = 914;
|
|
|
|
var locoLength = 450 * 0.3; // 0.3 is the scale factor
|
|
var carLength = 437 * 0.3; // 0.3 is the scale factor
|
|
|
|
|
|
|
|
// set the jmri global variable to null
|
|
var jmri = null;
|
|
$(document).ready(function() {
|
|
|
|
calculateDivergingTrackAngle();
|
|
|
|
jmri = $.JMRI({
|
|
|
|
open: function() {
|
|
jmri.getMemory("IM_7_1"); // Crane angle left - right, commanded position
|
|
jmri.getMemory("IM_7_2"); // Crane angle left - right, actual position
|
|
jmri.getMemory("IM_7_3"); // Crane bucket up - down, commanded position
|
|
jmri.getMemory("IM_7_4"); // Crane bucket up - down, actual position
|
|
jmri.getMemory("IM_7_5"); // Crane bucket closed - open, commanded position
|
|
jmri.getMemory("IM_7_6"); // Crane bucket closed - open, actual position
|
|
jmri.getTurnout("IT_7_1"); // Turnout
|
|
jmri.getSensor("IS_7_1"); // Sensor at turnout
|
|
jmri.getSensor("IS_7_2"); // Sensor at ship
|
|
jmri.getSensor("IS_7_3"); // Sensor at coal yard
|
|
|
|
// console.log("Throttle data: ");
|
|
// console.log("MyLoco throttle");
|
|
throttle = {"name": "MyLoco", "address": 21};
|
|
result = jmri.getThrottle(throttle);
|
|
},
|
|
|
|
|
|
memory: function(name, value, data) {
|
|
if (name == "IM_7_1") rotateCrane(value);
|
|
if (name == "IM_7_3") liftLowerCrane(value);
|
|
if (name == "IM_7_5") openCloseCraneBucket(value);
|
|
},
|
|
|
|
|
|
turnout: function(name, value, data) {
|
|
turnoutThrown = (value == 4);
|
|
|
|
if (turnoutThrown) {
|
|
turnout_1_1.setAttribute("visibility", "hidden");
|
|
turnout_1_2.setAttribute("visibility", "hidden");
|
|
turnout_2_1.setAttribute("visibility", "visible");
|
|
turnout_2_2.setAttribute("visibility", "visible");
|
|
} else {
|
|
turnout_1_1.setAttribute("visibility", "visible");
|
|
turnout_1_2.setAttribute("visibility", "visible");
|
|
turnout_2_1.setAttribute("visibility", "hidden");
|
|
turnout_2_2.setAttribute("visibility", "hidden");
|
|
}
|
|
},
|
|
|
|
|
|
throttle: function(throttle, data) {
|
|
if (typeof data.speed !== 'undefined') {
|
|
// console.log("Speed: ", data.speed);
|
|
if (data.speed >= 0) throttleSpeed = data.speed;
|
|
else throttleSpeed = 0;
|
|
}
|
|
if (typeof data.forward !== 'undefined') {
|
|
// console.log("Forward: ", data.forward);
|
|
throttleForward = data.forward;
|
|
}
|
|
// for (var key in data2) {
|
|
// console.log(key);
|
|
// }
|
|
},
|
|
|
|
|
|
// when the JMRI object receives a power update, call this
|
|
// function, regardless of source of update
|
|
power: function(state) {
|
|
power = state;
|
|
// console.log("Power: "+power);
|
|
/*
|
|
switch (power) {
|
|
case jmri.UNKNOWN:
|
|
$('#powerImg').prop('src', "/images/PowerGrey.png");
|
|
$('#powerImg').prop('alt', "Unknown");
|
|
$('#powerImg').prop('title', "Unknown");
|
|
break;
|
|
case jmri.POWER_ON:
|
|
$('#powerImg').prop('src', "/images/PowerGreen.png");
|
|
$('#powerImg').prop('alt', "Powered On");
|
|
$('#powerImg').prop('title', "Powered On");
|
|
break;
|
|
case jmri.POWER_OFF:
|
|
$('#powerImg').prop('src', "/images/PowerRed.png");
|
|
$('#powerImg').prop('alt', "Powered Off");
|
|
$('#powerImg').prop('title', "Powered Off");
|
|
break;
|
|
}
|
|
*/
|
|
}
|
|
});
|
|
// trigger the initial connection to the JMRI server; this
|
|
// method call ensures the jmri.open() method is called after
|
|
// a timeout to begin using fall back methods for monitoring
|
|
// items on the JMRI server even if a WebSocket connection
|
|
// cannot be established
|
|
jmri.connect();
|
|
|
|
// make it possible to click on the power button to turn track
|
|
// power on or off without using a javascript URI
|
|
// $('#powerImg').click(function(event) {
|
|
// jmri.setPower((power === jmri.POWER_ON) ? jmri.POWER_OFF : jmri.POWER_ON);
|
|
// });
|
|
});
|
|
|
|
|
|
|
|
function calculateDivergingTrackAngle()
|
|
{
|
|
var track = document.getElementById('DivergingCenterRail');
|
|
var x1 = parseFloat(track.getAttributeNS(null, 'x1'));
|
|
var y1 = parseFloat(track.getAttributeNS(null, 'y1'));
|
|
var x2 = parseFloat(track.getAttributeNS(null, 'x2'));
|
|
var y2 = parseFloat(track.getAttributeNS(null, 'y2'));
|
|
|
|
turnoutPos = x1;
|
|
|
|
var x = x2 - x1;
|
|
var y = y2 - y1;
|
|
|
|
diveringTrackAngle = Math.atan(y/x);
|
|
}
|
|
|
|
|
|
|
|
|
|
function moveLocoOrCar(item, pos)
|
|
{
|
|
var x = pos;
|
|
var y = 0;
|
|
var rotate = 0;
|
|
if (selectDivergedTrack && (pos > turnoutPos)) {
|
|
var posAfterTurnout = pos - turnoutPos;
|
|
rotate = diveringTrackAngle * 360 / 2 / Math.PI;
|
|
x = turnoutPos + posAfterTurnout * Math.cos(diveringTrackAngle);
|
|
y = posAfterTurnout * Math.sin(diveringTrackAngle);
|
|
}
|
|
var data = "translate("+x+","+(y+200)+") scale(0.3) rotate("+rotate+")";
|
|
item.setAttribute("transform", data);
|
|
}
|
|
|
|
|
|
|
|
function checkSensors()
|
|
{
|
|
var sensorTriggered = false;
|
|
sensorTriggered = (((locoPos-locoLength/2) <= sensor1_Pos) && ((locoPos+locoLength/2) >= sensor1_Pos));
|
|
sensorTriggered |= (((carPos-carLength/2) <= sensor1_Pos) && ((carPos+carLength/2) >= sensor1_Pos));
|
|
|
|
if (sensorTriggered) {
|
|
// Sensor 1 triggered
|
|
if (true || !sensor1_active) {
|
|
sensor1_active = true;
|
|
jmri.setSensor("IS_7_1", 2);
|
|
}
|
|
} else {
|
|
// Sensor 1 not triggered
|
|
if (true || sensor1_active) {
|
|
sensor1_active = false;
|
|
jmri.setSensor("IS_7_1", 4);
|
|
}
|
|
}
|
|
|
|
|
|
sensorTriggered = false;
|
|
if (!selectDivergedTrack) {
|
|
sensorTriggered = (((locoPos-locoLength/2) <= sensor2_Pos) && ((locoPos+locoLength/2) >= sensor2_Pos));
|
|
sensorTriggered |= (((carPos-carLength/2) <= sensor2_Pos) && ((carPos+carLength/2) >= sensor2_Pos));
|
|
}
|
|
if (sensorTriggered) {
|
|
// Sensor 2 triggered
|
|
if (true || !sensor2_active) {
|
|
sensor2_active = true;
|
|
jmri.setSensor("IS_7_2", 2);
|
|
}
|
|
} else {
|
|
// Sensor 2 not triggered
|
|
if (true || sensor2_active) {
|
|
sensor2_active = false;
|
|
jmri.setSensor("IS_7_2", 4);
|
|
}
|
|
}
|
|
|
|
|
|
sensorTriggered = false;
|
|
if (selectDivergedTrack) {
|
|
sensorTriggered = (((locoPos-locoLength/2) <= sensor3_Pos) && ((locoPos+locoLength/2) >= sensor3_Pos));
|
|
sensorTriggered |= (((carPos-carLength/2) <= sensor3_Pos) && ((carPos+carLength/2) >= sensor3_Pos));
|
|
}
|
|
if (sensorTriggered) {
|
|
// Sensor 3 triggered
|
|
if (true || !sensor3_active) {
|
|
sensor3_active = true;
|
|
jmri.setSensor("IS_7_3", 2);
|
|
}
|
|
} else {
|
|
// Sensor 3 not triggered
|
|
if (true || sensor3_active) {
|
|
sensor3_active = false;
|
|
jmri.setSensor("IS_7_3", 4);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
window.setInterval(runTrain, 50);
|
|
|
|
function runTrain()
|
|
{
|
|
jmri.setSensor("IS_7_2", "ACTIVE");
|
|
|
|
|
|
if (throttleSpeed != 0)
|
|
{
|
|
if (carPos < turnoutPos) selectDivergedTrack = turnoutThrown;
|
|
|
|
var speed = throttleSpeed;
|
|
if (throttleForward) speed = -speed;
|
|
|
|
locoPos += speed*2;
|
|
carPos = locoPos + 150;
|
|
|
|
var loco = document.getElementById('LocoHandle');
|
|
moveLocoOrCar(loco, locoPos);
|
|
|
|
var car = document.getElementById('CarHandle');
|
|
moveLocoOrCar(car, carPos);
|
|
} else {
|
|
if ((carPos >= 591) && (carPos <= 858) && !selectDivergedTrack) {
|
|
// Unload car
|
|
carIsFilled = false;
|
|
var carLoad = document.getElementById('CarLoad');
|
|
carLoad.setAttribute("visibility", "hidden");
|
|
}
|
|
}
|
|
|
|
// Check the sensors
|
|
checkSensors();
|
|
|
|
// Check the crane
|
|
checkCrane();
|
|
}
|
|
|
|
|
|
|
|
|
|
function rotateCrane(value) {
|
|
commandedCraneAngle = (craneMaxAngle - craneMinAngle) * value / 100 + craneMinAngle;
|
|
if (commandedCraneAngle < craneMinAngle) commandedCraneAngle = craneMinAngle;
|
|
if (commandedCraneAngle > craneMaxAngle) commandedCraneAngle = craneMaxAngle;
|
|
}
|
|
|
|
|
|
function liftLowerCrane(value) {
|
|
commandedCraneUpDown = value;
|
|
if (commandedCraneUpDown < 0) commandedCraneUpDown = 0;
|
|
if (commandedCraneUpDown > 100) commandedCraneUpDown = 100;
|
|
}
|
|
|
|
|
|
function openCloseCraneBucket(value) {
|
|
commandedCraneBucketOpenClosed = value;
|
|
if (commandedCraneBucketOpenClosed < 2) commandedCraneBucketOpenClosed = 2;
|
|
if (commandedCraneBucketOpenClosed > 100) commandedCraneBucketOpenClosed = 100;
|
|
}
|
|
|
|
|
|
function checkLoadingOfCar()
|
|
{
|
|
// If here, the crane bucket is filled, but the bucket is opened to drop its coal
|
|
|
|
// Check if crane bucket is close to the track
|
|
if ((craneAngle < 0) || (craneAngle > 60)) return;
|
|
|
|
// Calculate where the crane bucket are relative to the track
|
|
// 857 = position of the car when the car is below the crane bucket and the crane arm is
|
|
// perpendicular to the track.
|
|
var cranePosRelativeToTrack = Math.sin((craneAngle-30) * 2 * Math.PI / 360) * 2 * 57 + 857;
|
|
|
|
if (selectDivergedTrack && (Math.abs(carPos - cranePosRelativeToTrack) < carLength/3)) {
|
|
carIsFilled = true;
|
|
var carLoad = document.getElementById('CarLoad');
|
|
carLoad.setAttribute("visibility", "visible");
|
|
}
|
|
}
|
|
|
|
|
|
function checkCrane()
|
|
{
|
|
var lastAngle = craneAngle;
|
|
|
|
if (craneUpDown >= 80) {
|
|
if (commandedCraneAngle < craneAngle) {
|
|
craneAngle -= 1;
|
|
if (craneAngle < commandedCraneAngle) craneAngle = commandedCraneAngle;
|
|
}
|
|
if (commandedCraneAngle > craneAngle) {
|
|
craneAngle += 1;
|
|
if (craneAngle > commandedCraneAngle) craneAngle = commandedCraneAngle;
|
|
}
|
|
}
|
|
|
|
if (craneAngle != lastAngle) {
|
|
var item = document.getElementById('CraneHandle');
|
|
var data = "translate("+craneX+","+(craneY)+") scale(0.3) rotate("+craneAngle+")";
|
|
item.setAttribute("transform", data);
|
|
|
|
anglePercent = (craneAngle - craneMinAngle) / (craneMaxAngle - craneMinAngle) * 100;
|
|
jmri.setMemory("IM_7_2", anglePercent);
|
|
}
|
|
|
|
|
|
|
|
var lastCraneUpDown = craneUpDown;
|
|
if (commandedCraneUpDown < craneUpDown) {
|
|
craneUpDown -= 1;
|
|
if (craneUpDown < commandedCraneUpDown) craneUpDown = commandedCraneUpDown;
|
|
}
|
|
if (commandedCraneUpDown > craneUpDown) {
|
|
craneUpDown += 1;
|
|
if (craneUpDown > commandedCraneUpDown) craneUpDown = commandedCraneUpDown;
|
|
}
|
|
|
|
if (craneUpDown != lastCraneUpDown) {
|
|
var item = document.getElementById('CraneUpDown');
|
|
var data = "translate(0,0) rotate("+((100-craneUpDown)*1.80)+")";
|
|
item.setAttribute("transform", data);
|
|
|
|
jmri.setMemory("IM_7_4", craneUpDown);
|
|
}
|
|
|
|
|
|
|
|
var lastCraneBucketOpenClosed = craneBucketOpenClosed;
|
|
if (commandedCraneBucketOpenClosed < craneBucketOpenClosed) {
|
|
craneBucketOpenClosed -= 1;
|
|
if (craneBucketOpenClosed < commandedCraneBucketOpenClosed) craneBucketOpenClosed = commandedCraneBucketOpenClosed;
|
|
if (craneBucketFilled && (craneBucketOpenClosed < 50)) {
|
|
checkLoadingOfCar();
|
|
craneBucketFilled = false;
|
|
}
|
|
}
|
|
if (commandedCraneBucketOpenClosed > craneBucketOpenClosed) {
|
|
craneBucketOpenClosed += 1;
|
|
if (craneBucketOpenClosed > commandedCraneBucketOpenClosed) craneBucketOpenClosed = commandedCraneBucketOpenClosed;
|
|
if (!craneBucketFilled && (craneBucketOpenClosed > 50) && (craneUpDown < 20) && (anglePercent >= 22) && (anglePercent <= 48)) {
|
|
craneBucketFilled = true;
|
|
}
|
|
}
|
|
|
|
if (craneBucketOpenClosed != lastCraneBucketOpenClosed) {
|
|
var item = document.getElementById('CraneBucket');
|
|
var data = "translate(0,0) rotate("+((100-craneBucketOpenClosed)*1.80)+")";
|
|
item.setAttribute("height", craneBucketOpenClosed);
|
|
|
|
if (!craneBucketFilled) item.setAttribute("fill", "#4F81BD");
|
|
else item.setAttribute("fill", "#948A54");
|
|
|
|
jmri.setMemory("IM_7_6", craneBucketOpenClosed);
|
|
}
|
|
|
|
}
|