--[[
---------------------------------------------------------------------------
Remote Train Control Program for Windows

© Copyright 2019 by Mark DiVecchio

	This file is part of Remote Train Control.

	Remote Train Control is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	Remote Train Control is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with Remote Train Control.  If not, see <http://www.gnu.org/licenses/>.

 Home Page : http://www.silogic.com/trains/RTC_Running.html
---------------------------------------------------------------------------]]
-- Semicolons are not required in Lua code
title = "Speed Calculation Test"

require("defines");
require("functions");

LastRunTime = 0.0;
LastDTO = 0.0;
Accuracy = 0.01;	-- 1.00%

SaveAcc = 0;
SaveDec = 0;

MyEngineNo = 0;

--[[---------------------------------------------------------------------------------------]]
function setup(Engine, TIU)
	-- this function is called once when the [Run Script] button is pushed
	print("setup()");
	SetLED(1, clGreen, "Speed");	-- set status LED to green
	SetLED(2, clGreen, "%");	-- set status LED to green	
	-- Engine number selected on the Main window is used
	if (Debug() > 0) then print(string.format("Debug level %d", Debug())); end
	MyEngineNo = Engine;
	Resp = InputQuery("Numeric Input Required", "Enter Engine Number", MyEngineNo);
	if (Resp == false or Resp == nil) then	-- user pressed [Cancel]
		return false;	-- false=setup failed, true=setup succeeded
		end;
	Enum = tonumber(Resp);
	if (Enum ~= nil) then	-- if the result is a number, then use it, otherwise, ignore it
		MyEngineNo = Enum;
		end
	print("Engine Number = " .. MyEngineNo);
	
	-- initialize the layout
	print(string.format("Startup Engine : %d", MyEngineNo));
	EngineStartUp(MyEngineNo, TIU);
	Sleep(25);			
	if (IsEngineRunning(MyEngineNo)) then	-- IsEngineRunning() REQUIRES use of StartUpActiveEngines() or EngineStartUp()
		print(string.format("Initalizing Engine %d", MyEngineNo));
		-- Set smoke off
		Smoke(OFF, 0, MyEngineNo, TIU);
		-- Cab Chatter Off
		CabChat(OFF, 0, MyEngineNo, TIU);
		-- get DTO at start
		CurrentDTO = DTO(MyEngineNo, TIU);
		print(string.format("Trip odometer at start = %.3f Smiles", CurrentDTO));
		-- read up and save the Acc/Dec rates
		SaveAcc, SaveDec = GetRate(MyEngineNo, TIU);
		if (SaveAcc == nil or SaveDec == nil) then
			print(string.format("Get Acc/Dec Rates Failed for Engine : %d", MyEngineNo));
			return false;	-- false=setup failed, true=setup succeeded
			else
			print(string.format("Saved Acc/Dec Rates for Engine : %d : %d - %d", MyEngineNo, SaveAcc, SaveDec));
			end
		-- Set Acc/Dec rate to 25 Smph/sec
		Rate(25, 25, 0, MyEngineNo, TIU);
		print("Acc/Dec rates set to 25 Smph/sec");
		else
		print(string.format("Startup Failed for Engine : %d", MyEngineNo));
		return false;	-- false=setup failed, true=setup succeeded
		end
	print(string.format("Required Speed Accuracy : %.2f%%", Accuracy * 100.0));

	--Speeds = {5,11,15,22,26,33,38,44,50,55}
	Speeds = {30,40}
	for i,iSpeed in ipairs(Speeds) do
		print(string.format("SetSpeed %d Smph for Engine : %d", iSpeed, MyEngineNo));
		SetSpeed(iSpeed, 0, MyEngineNo, TIU);
		Sleep(10);			
		-- read up speed and check it against iSpeed
		CurrentSpeed = GetSetSpeed(MyEngineNo, TIU);
		if (CurrentSpeed ~= iSpeed) then
			print(string.format("Requested Speed Wrong : %d Smph", CurrentSpeed));
			SetLED(1, clRed);	-- set status LED to red
			--return false;
			else
			print(string.format("Requested Speed Correct : %d Smph", CurrentSpeed));
			end
		-- read up speed and check it against iSpeed
		InstantSpeed = GetSpeed(MyEngineNo, TIU);
		if (InstantSpeed ~= iSpeed) then
			print(string.format("Instantaneous Speed Wrong : %d Smph", InstantSpeed));
			SetLED(1, clRed);	-- set status LED to red
			--return false;
			else
			print(string.format("Instantaneous Speed Correct : %d Smph", InstantSpeed));
			end
		-- run for one test period
		print("Test " .. i .. " Started");
		LastDTO = DTO(MyEngineNo, TIU);
		LastRunTime = RunTime();
		Sleep(30);			
		-- read up time and distance and compare with iSpeed
		CurrentDTO = DTO(MyEngineNo, TIU);
		CurrentRunTime = RunTime();
		print(string.format("Run Time = %.2f seconds (%.2f-%.2f)", CurrentRunTime - LastRunTime, CurrentRunTime, LastRunTime)); 
		print(string.format("Distance = %.6f Smiles (%.6f-%.6f)", CurrentDTO - LastDTO, CurrentDTO, LastDTO)); 
		CalculatedSpeed = 3600 * (CurrentDTO - LastDTO)/(CurrentRunTime - LastRunTime);
		print(string.format("Calculated Speed = %.2f Smph (%.6f/%.2f)", CalculatedSpeed, CurrentDTO - LastDTO, CurrentRunTime - LastRunTime));
		print(string.format("Speed accurate to %.2f%%", 100.0 * (CurrentSpeed - CalculatedSpeed) / CurrentSpeed ));
		if ((CalculatedSpeed > (CurrentSpeed * (1 + Accuracy))) or (CalculatedSpeed < (CurrentSpeed * (1 - Accuracy)))) then
			print(string.format("*** Speed not within %.2f%% of expected", Accuracy * 100.0));
			Beep();
			SetLED(2, clRed);	-- set status LED to red
			end
		end
	Sleep(15);			
	print("Test Complete");
	return true;	-- false=setup failed, true=setup succeeded
	end
--[[---------------------------------------------------------------------------------------]]
function cleanup(Engine, TIU)
	-- this function is called once when the user presses the [STOP] button
	print("cleanup()");
	-- Restore Acc/Dec rates if saved
	if (SaveAcc > 0 and SaveDec > 0) then
		Rate(SaveAcc, SaveDec, 0, MyEngineNo, TIU);
		Sleep(1);
		SetSpeed(0, 0, MyEngineNo, TIU);
		Sleep(10);
		print("Shutdown Engine " .. MyEngineNo .. " - Please Wait");
		EngineShutdown(MyEngineNo, TIU);
		end;
	print("Script Finished");
	return true;		-- false=cleanup failed, true=cleanup succeeded
	end
--[[---------------------------------------------------------------------------------------]]
function StopEngine(Eng, TIU)		
	print("Stopping Engine " .. MyEngineNo);
	SetSpeed(0, 0, MyEngineNo, TIU);
	return true;
end
Function01Name, Function01Label = StopEngine, "Stop";
--[[---------------------------------------------------------------------------------------]]
function StartEngine(Eng, TIU)		
	print("Starting Engine " .. MyEngineNo);
	SetSpeed(20, 0, MyEngineNo, TIU);	
	return true;
end
Function02Name, Function02Label = StartEngine, "Start 20 Smph";
--[[---------------------------------------------------------------------------------------]]
function Forward(Eng, TIU)		
	print("Forward Engine " .. MyEngineNo);
	SetDirection(FORWARD, 0, MyEngineNo, TIU);
	return true;
end
Function03Name, Function03Label = Forward, "Forward";
--[[---------------------------------------------------------------------------------------]]
function Reverse(Eng, TIU)	
	print("Reverse Engine " .. MyEngineNo);
	SetDirection(REVERSE, 0, MyEngineNo, TIU);
	return true;
end
Function04Name, Function04Label = Reverse, "Reverse";
--[[---------------------------------------------------------------------------------------]]
--[[-----------------------------------------
Success compiling C:\trains\MTH\PC Control\Scripts\Speed Calculation Test.lua
Function Function01Name OK
Function Function02Name OK
Function Function03Name OK
Function Function04Name OK
setup()
Debug level 2
stackDump(L)
 1 : string Numeric Input Required
 2 : string Enter Engine Number
 3 : integer 11
-------
Engine Number = 11
Startup Engine : 11
Initalizing Engine 11
FetchDTO=1.301642 raw=452909 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Trip odometer at start = 1.302 Smiles
Saved Acc/Dec Rates for Engine : 11 : 1 - 1
Acc/Dec rates set to 25 Smph/sec
Required Speed Accuracy : 1.00%
SetSpeed 5 Smph for Engine : 11
Requested Speed Correct : 5 Smph
Instantaneous Speed Correct : 5 Smph
Test 1 Started
FetchDTO=1.314788 raw=457483 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=1.357009 raw=472174 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.50 seconds (77.40-46.90)
Distance = 0.042221 Smiles (1.357009-1.314788)
Calculated Speed = 4.98 Smph (0.042221/30.50)
Speed accurate to 0.33%
SetSpeed 11 Smph for Engine : 11
Requested Speed Correct : 11 Smph
Instantaneous Speed Correct : 11 Smph
Test 2 Started
FetchDTO=1.404984 raw=488867 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=1.497810 raw=521166 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.50 seconds (123.80-93.30)
Distance = 0.092826 Smiles (1.497810-1.404984)
Calculated Speed = 10.96 Smph (0.092826/30.50)
Speed accurate to 0.40%
SetSpeed 15 Smph for Engine : 11
Requested Speed Correct : 15 Smph
Instantaneous Speed Correct : 15 Smph
Test 3 Started
FetchDTO=1.563885 raw=544157 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=1.690753 raw=588301 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.40 seconds (170.30-139.90)
Distance = 0.126868 Smiles (1.690753-1.563885)
Calculated Speed = 15.02 Smph (0.126868/30.40)
Speed accurate to 0.16%
SetSpeed 22 Smph for Engine : 11
Requested Speed Correct : 22 Smph
Instantaneous Speed Correct : 22 Smph
Test 4 Started
FetchDTO=1.787175 raw=621851 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=1.973554 raw=686702 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.60 seconds (216.90-186.30)
Distance = 0.186379 Smiles (1.973554-1.787175)
Calculated Speed = 21.93 Smph (0.186379/30.60)
Speed accurate to 0.33%
SetSpeed 26 Smph for Engine : 11
Requested Speed Correct : 26 Smph
Instantaneous Speed Correct : 26 Smph
Test 5 Started
FetchDTO=2.088162 raw=726580 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=2.307988 raw=803069 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.50 seconds (263.40-232.90)
Distance = 0.219826 Smiles (2.307988-2.088162)
Calculated Speed = 25.95 Smph (0.219826/30.50)
Speed accurate to 0.20%
SetSpeed 33 Smph for Engine : 11
Requested Speed Correct : 33 Smph
Instantaneous Speed Correct : 33 Smph
Test 6 Started
FetchDTO=2.453551 raw=853718 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=2.732785 raw=950878 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.50 seconds (309.90-279.40)
Distance = 0.279234 Smiles (2.732785-2.453551)
Calculated Speed = 32.96 Smph (0.279234/30.50)
Speed accurate to 0.12%
SetSpeed 38 Smph for Engine : 11
Requested Speed Correct : 38 Smph
Instantaneous Speed Correct : 38 Smph
Test 7 Started
FetchDTO=2.900800 raw=1009339 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=3.222355 raw=1121225 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.50 seconds (356.40-325.90)
Distance = 0.321556 Smiles (3.222355-2.900800)
Calculated Speed = 37.95 Smph (0.321556/30.50)
Speed accurate to 0.12%
SetSpeed 44 Smph for Engine : 11
Requested Speed Correct : 44 Smph
Instantaneous Speed Correct : 44 Smph
Test 8 Started
FetchDTO=3.416319 raw=1188715 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=3.788405 raw=1318183 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.50 seconds (402.90-372.40)
Distance = 0.372086 Smiles (3.788405-3.416319)
Calculated Speed = 43.92 Smph (0.372086/30.50)
Speed accurate to 0.19%
SetSpeed 50 Smph for Engine : 11
Requested Speed Correct : 50 Smph
Instantaneous Speed Correct : 50 Smph
Test 9 Started
FetchDTO=4.009162 raw=1394996 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=4.431752 raw=1542037 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.50 seconds (449.40-418.90)
Distance = 0.422590 Smiles (4.431752-4.009162)
Calculated Speed = 49.88 Smph (0.422590/30.50)
Speed accurate to 0.24%
SetSpeed 55 Smph for Engine : 11
Requested Speed Correct : 55 Smph
Instantaneous Speed Correct : 55 Smph
Test 10 Started
FetchDTO=4.675220 raw=1626752 DTOFACTOR=11.000000 ScaleFactor=31632.00 
FetchDTO=5.140387 raw=1788608 DTOFACTOR=11.000000 ScaleFactor=31632.00 
Run Time = 30.50 seconds (496.00-465.50)
Distance = 0.465168 Smiles (5.140387-4.675220)
Calculated Speed = 54.91 Smph (0.465168/30.50)
Speed accurate to 0.17%
Test Complete
cleanup()
Shutdown Engine 11 - Please Wait
Script Finished



Success compiling C:\trains\MTH\PC Control\Scripts\Speed Calculation Test.lua
setup()
Engine Number = 12
Startup Engine : 12
Initalizing Engine 12
Trip odometer at start = 0.370 Smiles
Saved Acc/Dec Rates for Engine : 12 : 1 - 1
Acc/Dec rates set to 25 Smph/sec
Required Speed Accuracy : 1.00%
SetSpeed 5 Smph for Engine : 12
Requested Speed Correct : 5 Smph
Instantaneous Speed Correct : 5 Smph
Test 1 Started
Run Time = 30.50 seconds (73.90-43.40)
Distance = 0.042436 Smiles (0.418437-0.376002)
Calculated Speed = 5.01 Smph (0.042436/30.50)
Speed accurate to -0.18%
SetSpeed 11 Smph for Engine : 12
Requested Speed Correct : 11 Smph
Instantaneous Speed Correct : 11 Smph
Test 2 Started
Run Time = 30.50 seconds (115.50-85.00)
Distance = 0.093199 Smiles (0.544455-0.451256)
Calculated Speed = 11.00 Smph (0.093199/30.50)
Speed accurate to -0.00%
SetSpeed 15 Smph for Engine : 12
Requested Speed Correct : 15 Smph
Instantaneous Speed Correct : 15 Smph
Test 3 Started
Run Time = 30.50 seconds (157.00-126.50)
Distance = 0.127013 Smiles (0.716870-0.589857)
Calculated Speed = 14.99 Smph (0.127013/30.50)
Speed accurate to 0.06%
SetSpeed 22 Smph for Engine : 12
Requested Speed Correct : 22 Smph
Instantaneous Speed Correct : 22 Smph
Test 4 Started
Run Time = 30.50 seconds (198.50-168.00)
Distance = 0.186431 Smiles (0.969547-0.783116)
Calculated Speed = 22.01 Smph (0.186431/30.50)
Speed accurate to -0.02%
SetSpeed 26 Smph for Engine : 12
Requested Speed Correct : 26 Smph
Instantaneous Speed Correct : 26 Smph
Test 5 Started
Run Time = 30.60 seconds (240.10-209.50)
Distance = 0.220842 Smiles (1.269307-1.048465)
Calculated Speed = 25.98 Smph (0.220842/30.60)
Speed accurate to 0.07%
SetSpeed 33 Smph for Engine : 12
Requested Speed Correct : 33 Smph
Instantaneous Speed Correct : 33 Smph
Test 6 Started
Run Time = 30.50 seconds (281.60-251.10)
Distance = 0.279689 Smiles (1.648615-1.368926)
Calculated Speed = 33.01 Smph (0.279689/30.50)
Speed accurate to -0.04%
SetSpeed 38 Smph for Engine : 12
Requested Speed Correct : 38 Smph
Instantaneous Speed Correct : 38 Smph
Test 7 Started
Run Time = 30.50 seconds (323.10-292.60)
Distance = 0.322436 Smiles (2.086065-1.763629)
Calculated Speed = 38.06 Smph (0.322436/30.50)
Speed accurate to -0.15%
SetSpeed 44 Smph for Engine : 12
Requested Speed Correct : 44 Smph
Instantaneous Speed Correct : 44 Smph
Test 8 Started
Run Time = 30.50 seconds (364.60-334.10)
Distance = 0.372821 Smiles (2.592554-2.219733)
Calculated Speed = 44.01 Smph (0.372821/30.50)
Speed accurate to -0.01%
SetSpeed 50 Smph for Engine : 12
Requested Speed Correct : 50 Smph
Instantaneous Speed Correct : 50 Smph
Test 9 Started
Run Time = 30.60 seconds (406.20-375.60)
Distance = 0.424252 Smiles (3.169108-2.744856)
Calculated Speed = 49.91 Smph (0.424252/30.60)
Speed accurate to 0.18%
SetSpeed 55 Smph for Engine : 12
Requested Speed Correct : 55 Smph
Instantaneous Speed Correct : 55 Smph
Test 10 Started
Run Time = 30.50 seconds (447.70-417.20)
Distance = 0.467272 Smiles (3.802628-3.335356)
Calculated Speed = 55.15 Smph (0.467272/30.50)
Speed accurate to -0.28%
Test Complete
cleanup()
Shutdown Engine 12 - Please Wait
Script Finished

----------------------------------------------]]


