--[[
---------------------------------------------------------------------------
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
-- This script measures the distance between the tags on the layout.
-- 
title = "Tag DTO Distance Test"
require("defines");
require("functions");

local TagCount = 0;
-- Counter Labels
Counter01Label = "tags()";
Counter02Label = "nametags()";
Counter03Label = "uidtags()";
Counter04Label = "response()";

local Tags = {};		-- table to hold all of the tags detected in sequence

local SoundOn = false;	-- start with annoying beep() off

DTOLast = 0;
DODLast = 0;
DTOCurrent = 0;
DODCurrent = 0;
DetectorLast = 0;
ReaderLast = 0;

Accuracy= 0.015;

-- Configuration Variables
local AutoBellWhistle = true;

-- Constructor output example
-- distance between two tag readers in inches. Tag reader number is ((Detector * 10) + Reader).
-- Distance given by TestOut[R1][R2].
TestOut = {[20] = {[40] = 139.80496371955, }, [40] = {[50] = 280.15344086518, }, [50] = {[30] = 40.563848962425, }, [30] = {[51] = 56.647409529972, }, [51] = {[10] = 207.28936543883, }, [10] = {[41] = 952.71802930166, }, [41] = {[21] = 146.69316448676, }, [21] = {[20] = 286.09326616444, }, };
--
-- Measured Distances substituted into TestOut for segment that I measured with a tape measure
--
MeasuredDistance = {[20] = {[40] = 139.25, }, [40] = {[50] = 278.5, }, [50] = {[30] = 40.5, }, [30] = {[51] = 56.647409529972, }, [51] = {[10] = 207.28936543883, }, [10] = {[41] = 952.71802930166, }, [41] = {[21] = 147.25, }, [21] = {[20] = 286.09326616444, }, };

--[[---------------------------------------------------------------------------------------]]
function setup(Engine, TIU)
	-- this function is called once when the [Run Script] button is pushed
	-- Engine : Engine number selected on the RTC Main window
	-- TIU : TIU number selected on the RTC Main window
	print("setup()");

	-- make sure that RFID is connected
	TIUSerialPortConnected, TIUConnected, RFIDSerialPortConnected = CommStatus();	
	--print("TIUSerialPortConnected : " .. tostring(TIUSerialPortConnected) .. " - TIUConnected : " .. tostring(TIUConnected) .. " - RFIDSerialPortConnected : " .. tostring(RFIDSerialPortConnected));
	if (not RFIDSerialPortConnected) then
		print("RFID Port must be enabled for this script");
		return false;	-- false=setup failed
		end
	TableConstructor = "{";
	MyEngineNo = Engine;	-- Engine number selected on the RTC Main window
	MyTIUNo = TIU;		-- TIU number selected on the RTC Main window
	-- debug level as selected on the Debug window, values 0 (off) to 9 (maximum)
	if (Debug() > 0) then 
		print(string.format("setup(): Debug level %d", Debug())); 
		print("setup(): Engine Number ", MyEngineNo ," TIU Number ", MyTIUNo);
		end
	Name, PS = GetName(MyEngineNo);
	print("Engine#" .. MyEngineNo .. " " .. Name .. " PS" .. PS);
	print("TIU : " .. MyTIUNo);
	print("Accuracy Limit = " .. Accuracy * 100 .. "%");
	Title(title .. " - " .. GetName(Engine));
	assert((MyTIUNo >= 1 and MyTIUNo <= 5),"TIU Number out of range");
	--
	print(string.format("Run Time = %.2f Seconds", RunTime()));
	Smoke(OFF, 0, MyEngineNo, MyTIUNo);
	StartUp(0, MyEngineNo, MyTIUNo);	-- start selected engine
	-- let engine startup
	Sleep(11.4);
	print(string.format("Run Time = %.2f Seconds", RunTime()));
	
	-- read up initial DTO
	DTOInitial = DTO(MyEngineNo, MyTIUNo);
	DTOLast = 0

	EngSpeed = 20;
	print("setup : Set speed to " .. EngSpeed);
	Throttle(EngSpeed, 0, MyEngineNo, MyTIUNo); -- set Speed to EngSpeed
	return true;		-- false=setup failed, true=setup succeeded
	end
--[[---------------------------------------------------------------------------------------]]
function tag(Detector, Reader, EngineNo, TagLocation, CarModel, Railroad, CarNumber, TagPacket)
	-- This function is called each time a tag programmed with 32 bytes of data is detected (TAGDATABLOCK4)
	-- TagPacket contains 8 characters (4 hex digits) of UID and 32 characters
	-- of block 4 data from the programmed tag.
	if (EngineNo ~= MyEngineNo) then return true; end;
	if (SoundOn) then Beep(DEFAULT_BEEP); end;	-- sound a tone
	BumpCounter(COUNTER01);	
	PacketLen = #TagPacket;

	if (Debug() >= 2) then print("Packet Length = ", PacketLen); end;
	if (Debug() >= 5) then print(TagPacket);	end;
---[=[
---------------------------------------------------------------------------	
	-- index the table Tags[] by tag ID, value is the tag packet itself
	Tags[string.sub(TagPacket, 1, 8)] = string.sub(TagPacket, 9, 40);	-- remove checksum and EOP
	TagCount = TagCount + 1;	-- count the number of tags
	
	if (isEngine(EngineNo) and isTagFront(TagLocation)) then	-- its an engine and front tag
		-- next line shows a different way to quote a string using brackets
		if (Debug() >= 1) then 
			print(string.format([[tag(%.2fs) : Detector %d Reader %d Eng#%d %s %s #%s %s]],
				RunTime(), Detector, Reader, EngineNo, GetRailroadName(Railroad), GetEngineName(CarModel), CarNumber, GetTagLocation(TagLocation)));
			end;
		-- find distance between tags
		if (DTOLast == 0) then
			-- its the first detector
			DTOLast = DTO(MyEngineNo, MyTIUNo) - DTOInitial;

			DetectorLast = Detector;
			ReaderLast = Reader;
			print(string.format("(%.2fs) Detector = %d Reader = %d DTO = %.3f Seconds", RunTime(), Detector, Reader, 0));
			else
			-- following tags		
			DTOCurrent = DTO(MyEngineNo, MyTIUNo) - DTOInitial;

			DTODelta = DTOCurrent - DTOLast;
			DTOInches = DTODelta * 5280 * 12 / 48;	-- convert Smiles to real inches
			print(string.format("(%.2fs) Detector = %d Reader = %d DTO = %.3f Smiles Delta DTO = %.3f Smiles (%.3f inches)",
				RunTime(), Detector, Reader, DTOCurrent, DTODelta, DTOInches));
			ExpectedInches = TestOut[(DetectorLast * 10) + ReaderLast][(Detector * 10) + Reader];
			ErrorInches = DTOInches - ExpectedInches;
			Message =  string.format("   Inches   = %.3f         -          Expected Inches = %.3f Error = %.3f Inches (%.3f%%)",
				DTOInches, ExpectedInches, ErrorInches, (100 * ErrorInches/ExpectedInches));
			if (math.abs(ErrorInches) > (ExpectedInches * Accuracy)) then 		-- accuracy 1.5%
				Beep();
				printc(clGreen, Message); 
				else
				printc(clBlack, Message); 
				end;
			TableConstructor = TableConstructor .. "[" .. (DetectorLast * 10) + ReaderLast .. "] = {[" .. (Detector * 10) + Reader .. "] = " .. DTOInches .. ", }, ";
			DTOLast = DTOCurrent;

			DetectorLast = Detector;
			ReaderLast = Reader;
			end
		else	-- it's a car
		--print(string.format([[tag(%.2f) : Detector %d Reader %d Car %s %s #%s]],
		--	RunTime(), Detector, Reader, GetRailroadName(Railroad), GetCarName(CarModel), CarNumber));
		-- ignore non engine tags
		return true;	-- true=continue to process tags, false=stop processing tags
		end

	-- The complete packet received is in TagPacket 
	-- (all of the fields have already been extracted into the first parameters to tag()
	--   First 8 digits are the 4 byte Tag UID in hexidecimal
	--   Next 32 digits are the 16 bytes of Block 4 Information read from the Tag in hexidecimal
	if (Debug() >= 3) then print(string.format("Packet  %s  %s", string.sub(TagPacket, 1, 8),
		string.sub(TagPacket,9,40) )); end

	return true;	-- true=continue to process tags, false=stop processing tags
	end
---------------------------------------------------------------------------]=]
function nametag(Detector, Reader, UID, CarName)
	-- This function is called each time a tag programmed with 32 bytes of car name is detected (TAGDATABLOCK5)
	-- UID contains 8 characters (4 hex digits) of UID and CarName contains 32 characters of car name
	-- of block 5 data from the programmed tag. 
	Beep(QUESTION);	-- sound a tone
	BumpCounter(COUNTER02);	
	UIDLen = #UID;
	CarNameLen = #CarName
	if (Debug() >= 2) then print("UID Length = ", UIDLen); end;
	if (Debug() >= 2) then print("CarName Length = ", CarNameLen); end;
	print(string.format([[nametag(%.2f) : Detector %d Reader %d]], RunTime(), Detector, Reader));
	if (Debug() >= 3) then print(string.format("UID  %s", string.sub(UID, 1, 8))); end	
	if (Debug() >= 3) then print(string.format("Car Name  %s", string.sub(CarName, 1, 16))); end	
	return true;	-- true=continue to process tags, false=stop processing tags
	end
--[[---------------------------------------------------------------------------------------]]
	
function uidtag(Detector, Reader, UID)
	-- This function is called each time an unprogrammed tag (TAGDETECTED) is detected
	-- Only the tag UID is returned
	-- UID contains 8 characters (4 hex digits) of UID	.
	-- When used as an error catch all, it could call EmergencyStop().	
	Beep(CRITICAL_STOP);	-- sound a tone
	BumpCounter(COUNTER03);	
	UIDLen = #UID;
	if (Debug() >= 2) then print("UID Length = ", UIDLen); end;
	print(string.format([[uidtag(%.2f) : Detector %d Reader %d]], RunTime(), Detector, Reader));
	--   8 digits are the 4 byte Tag UID in hexidecimal
	if (Debug() >= 3) then print(string.format("UID  %s", string.sub(UID, 1, 8))); end		
	TagCount = TagCount + 1;	-- count the number of tags	
	return true;	-- true=continue to process tags, false=stop processing tags
	end
--[[---------------------------------------------------------------------------------------]]
function response(Detector, Reader, Type, RespPacket)
	-- This function is called for all response from the Detectors
	-- This means that for regular block 4 tags (TAGDATABLOCK4) and for UID only tags (TAGDETECTED), this
	-- function is called right after tag() or uidtag() is called.
	-- It is up the user to skip those responses if he does want to do additional processing.
	-- RespPacket may contain a variable number of characters - inlcudes all header fields, data fields and trailer fields 
	-- THIS IS ONLY USEFUL WHEN DEBUGGING.
	-- Using this function requires an understanding of the RAW Tag Packet format.
	-- When used as an error catch all, it could call EmergencyStop() except for packets
	-- which called tag() (TAGDATABLOCK4) and uidtag() (TAGDETECTED).
	--Beep();	-- sound a tone
	BumpCounter(COUNTER04);	
	if (Debug() < 1) then return true; end;
	PacketLen = #RespPacket;
	-- Packet Types are defined in defines.lua
	if (Debug() >= 2) then print(string.format("Packet Length = %d Packet Type = 0x%02X", PacketLen, Type)); end;
	print(string.format([[response(%.2f) : Detector %d Reader %d Packet Type = 0x%02X]], RunTime(), Detector, Reader, Type));
	-- The complete packet received is in "RespPacket" - inlcudes all header fields, data fields and trailer fields 
	if (Debug() >= 3) then print(string.format("Response Packet  %s", RespPacket)); end		
	return true;	-- true=continue to process tags, false=stop processing tags
	end
--[[---------------------------------------------------------------------------------------]]
function cleanup(Engine, TIU)
	-- this function is called once when the user presses the [STOP] button
	--if (Acc >= 0 and Dec >= 0 ) then
	--	Rate(Acc, Dec, 0, MyEngineNo, MyTIUNo);	-- restore accel and decel rates	
	--	end;
	Sleep(2);
	Throttle(0, 0, MyEngineNo, MyTIUNo);
	Sleep(12);
	DTOFinish = DTO(MyEngineNo, MyTIUNo);
	-- wait for dispatch list to empty
	while(CountDispatchList() > 0) do Sleep(1); end
	print(string.format("Run Time = %.2f Seconds", RunTime()));
	print(string.format("Trip Odometer Finish %.2f Smiles", DTOFinish));
	ShutDown(0, MyEngineNo, MyTIUNo);

	if (TableConstructor ~= nil) then
		TableConstructor = TableConstructor .. "}"; 
		print (TableConstructor);
		end;
	
	print("All Newly Detected Tags:");
	for k,v in  pairs(Tags) do		-- dump out the Tags table
		--                           . . . . . . . . . . . . . . . .
		-- print format:  6619044A  88080101030108011B02202031353536
		print(k .. "  " .. v);
		end
	print(string.format("cleanup() Complete at %.2f", RunTime()));
	--
	return true;		-- false=cleanup failed, true=cleanup succeeded
	end
--[[---------------------------------------------------------------------------------------]]
function tick(Engine, TIU)
	-- this is called once per second while waiting for RFID tags to arrive
	-- Do not call Sleep() from this function
	if (Debug() > 6) then print(string.format("RunTime = %.2f Seconds", RunTime())); end;
	return true;
	end
--[[---------------------------------------------------------------------------------------]]
function DTOButton(Eng, TIU)
	print(string.format("Engine %d Trip Odometer %.3f Smiles", Eng, DTO(Eng, TIU)));
	return true;
end
Function01Name, Function01Label = DTOButton, "Show DTO";
--[[---------------------------------------------------------------------------------------]]
function DODButton(Eng, TIU)
	print(string.format("Engine %d Odometer %.3f Smiles", Eng, DOD(Eng, TIU)));
	return true;
end
Function02Name, Function02Label = DODButton, "Show DOD";
--[[---------------------------------------------------------------------------------------]]
function DCHButton(Eng, TIU)
	print(string.format("Engine %d Chronometer %.3f Seconds", Eng, DCH(Eng, TIU)));
	return true;
end
Function03Name, Function03Label = DCHButton, "Show DCH";
--[[---------------------------------------------------------------------------------------]]
function BeepOffButton(Eng, TIU)
	print("Beep Off");
	SoundOn = false;
	return true;
end
Function04Name, Function04Label = BeepOffButton, "Beep Off";
--[[---------------------------------------------------------------------------------------]]
function BeepOnButton(Eng, TIU)
	print("Beep On");
	SoundOn = true;
	return true;
end
Function05Name, Function05Label = BeepOnButton, "Beep On";
--[[---------------------------------------------------------------------------------------]]
function IncAcc(Eng, TIU)
Accuracy = Accuracy + 0.001;
print("Accuracy = " .. Accuracy);
return true;
end;
Function06Name, Function06Label = IncAcc, "Accuracy +0.001";
--[[---------------------------------------------------------------------------------------]]
function DecAcc(Eng, TIU)
Accuracy = Accuracy - 0.001;
print("Accuracy = " .. Accuracy);
return true;
end;
Function07Name, Function07Label = DecAcc, "Accuracy -0.001";
--[[---------------------------------------------------------------------------------------]]
--[[
---------------------------------------------------------------------------
Success compiling C:\trains\MTH\PC Control\Scripts\Tag DTO Distance Test.lua
setup()
Engine#13 P&LE GP7 #1500   PS3
TIU : 1
Run Time = 0.10 Seconds
Run Time = 7.50 Seconds
Acc = 1 Dec = 1
setup : Set speed to 20
Waiting for RFID Tag Detection
(29.90s) Detector = 5 Reader = 0 DTO = 0.000 Seconds DOD = 0.000 Seconds
(35.50s) Detector = 3 Reader = 0 DTO = 0.132 Smiles Delta DTO = 0.031 Smiles (40.875 inches)
   Inches   = 40.875         -          Expected Inches = 40.564 Error = -0.311 Inches
(43.20s) Detector = 5 Reader = 1 DTO = 0.176 Smiles Delta DTO = 0.043 Smiles (57.063 inches)
   Inches   = 57.063         -          Expected Inches = 56.647 Error = -0.416 Inches
(71.60s) Detector = 1 Reader = 0 DTO = 0.333 Smiles Delta DTO = 0.157 Smiles (207.480 inches)
   Inches   = 207.480         -          Expected Inches = 207.289 Error = -0.190 Inches
(202.50s) Detector = 4 Reader = 1 DTO = 1.059 Smiles Delta DTO = 0.726 Smiles (958.322 inches)
   Inches   = 958.322         -          Expected Inches = 952.718 Error = -5.604 Inches
(222.50s) Detector = 2 Reader = 1 DTO = 1.170 Smiles Delta DTO = 0.111 Smiles (146.940 inches)
   Inches   = 146.940         -          Expected Inches = 146.693 Error = -0.247 Inches
(261.70s) Detector = 2 Reader = 0 DTO = 1.387 Smiles Delta DTO = 0.217 Smiles (286.909 inches)
   Inches   = 286.909         -          Expected Inches = 286.093 Error = -0.816 Inches
(280.90s) Detector = 4 Reader = 0 DTO = 1.494 Smiles Delta DTO = 0.106 Smiles (140.102 inches)
   Inches   = 140.102         -          Expected Inches = 139.805 Error = -0.297 Inches 
(319.50s) Detector = 5 Reader = 0 DTO = 1.708 Smiles Delta DTO = 0.214 Smiles (282.530 inches)
   Inches   = 282.530         -          Expected Inches = 280.153 Error = -2.377 Inches
(325.10s) Detector = 3 Reader = 0 DTO = 1.739 Smiles Delta DTO = 0.031 Smiles (40.875 inches)
   Inches   = 40.875         -          Expected Inches = 40.564 Error = -0.311 Inches
(332.80s) Detector = 5 Reader = 1 DTO = 1.782 Smiles Delta DTO = 0.043 Smiles (56.819 inches)
   Inches   = 56.819         -          Expected Inches = 56.647 Error = -0.172 Inches 
(361.20s) Detector = 1 Reader = 0 DTO = 1.939 Smiles Delta DTO = 0.158 Smiles (207.911 inches)
   Inches   = 207.911         -          Expected Inches = 207.289 Error = -0.622 Inches
(492.70s) Detector = 4 Reader = 1 DTO = 2.668 Smiles Delta DTO = 0.729 Smiles (962.547 inches)
   Inches   = 962.547         -          Expected Inches = 952.718 Error = -9.829 Inches
(512.80s) Detector = 2 Reader = 1 DTO = 2.780 Smiles Delta DTO = 0.112 Smiles (147.377 inches)
   Inches   = 147.377         -          Expected Inches = 146.693 Error = -0.684 Inches
(552.10s) Detector = 2 Reader = 0 DTO = 2.998 Smiles Delta DTO = 0.218 Smiles (287.574 inches)
   Inches   = 287.574         -          Expected Inches = 286.093 Error = -1.480 Inches
(571.30s) Detector = 4 Reader = 0 DTO = 3.104 Smiles Delta DTO = 0.106 Smiles (140.551 inches)
   Inches   = 140.551         -          Expected Inches = 139.805 Error = -0.746 Inches
(609.90s) Detector = 5 Reader = 0 DTO = 3.319 Smiles Delta DTO = 0.214 Smiles (282.746 inches)
   Inches   = 282.746         -          Expected Inches = 280.153 Error = -2.593 Inches
(615.60s) Detector = 3 Reader = 0 DTO = 3.350 Smiles Delta DTO = 0.031 Smiles (41.517 inches)
   Inches   = 41.517         -          Expected Inches = 40.564 Error = -0.953 Inches
(623.40s) Detector = 5 Reader = 1 DTO = 3.393 Smiles Delta DTO = 0.043 Smiles (56.836 inches)
   Inches   = 56.836         -          Expected Inches = 56.647 Error = -0.189 Inches
(651.80s) Detector = 1 Reader = 0 DTO = 3.551 Smiles Delta DTO = 0.158 Smiles (208.127 inches)
   Inches   = 208.127         -          Expected Inches = 207.289 Error = -0.838 Inches
(783.10s) Detector = 4 Reader = 1 DTO = 4.279 Smiles Delta DTO = 0.728 Smiles (961.462 inches)
   Inches   = 961.462         -          Expected Inches = 952.718 Error = -8.744 Inches
(803.20s) Detector = 2 Reader = 1 DTO = 4.391 Smiles Delta DTO = 0.111 Smiles (147.156 inches)
   Inches   = 147.156         -          Expected Inches = 146.693 Error = -0.463 Inches
(842.50s) Detector = 2 Reader = 0 DTO = 4.609 Smiles Delta DTO = 0.218 Smiles (287.790 inches)
   Inches   = 287.790         -          Expected Inches = 286.093 Error = -1.696 Inches
(861.70s) Detector = 4 Reader = 0 DTO = 4.715 Smiles Delta DTO = 0.106 Smiles (140.313 inches)
   Inches   = 140.313         -          Expected Inches = 139.805 Error = -0.508 Inches
(900.40s) Detector = 5 Reader = 0 DTO = 4.929 Smiles Delta DTO = 0.215 Smiles (283.194 inches)
   Inches   = 283.194         -          Expected Inches = 280.153 Error = -3.041 Inches
(906.00s) Detector = 3 Reader = 0 DTO = 4.960 Smiles Delta DTO = 0.031 Smiles (40.836 inches)
   Inches   = 40.836         -          Expected Inches = 40.564 Error = -0.272 Inches
(913.80s) Detector = 5 Reader = 1 DTO = 5.004 Smiles Delta DTO = 0.043 Smiles (57.074 inches)
   Inches   = 57.074         -          Expected Inches = 56.647 Error = -0.427 Inches
(942.20s) Detector = 1 Reader = 0 DTO = 5.161 Smiles Delta DTO = 0.158 Smiles (208.100 inches)
   Inches   = 208.100         -          Expected Inches = 207.289 Error = -0.810 Inches
[STOP]
Run Time = 972.20 Seconds
Trip Odometer Finish 5.28 Smiles
{[50] = {[30] = 40.874740484429, }, [30] = {[51] = 57.062975778547, }, [51] = {[10] = 207.47958477509, }, [10] = {[41] = 958.32249134948, }, [41] = {[21] = 146.93979238754, }, [21] = {[20] = 286.90934256055, }, [20] = {[40] = 140.10242214533, }, [40] = {[50] = 282.53010380623, }, [50] = {[30] = 40.874740484429, }, [30] = {[51] = 56.81937716263, }, [51] = {[10] = 207.91141868512, }, [10] = {[41] = 962.54671280277, }, [41] = {[21] = 147.37716262976, }, [21] = {[20] = 287.57370242215, }, [20] = {[40] = 140.5508650519, }, [40] = {[50] = 282.74602076125, }, [50] = {[30] = 41.516955017301, }, [30] = {[51] = 56.83598615917, }, [51] = {[10] = 208.12733564014, }, [10] = {[41] = 961.4615916955, }, [41] = {[21] = 147.15570934256, }, [21] = {[20] = 287.78961937716, }, [20] = {[40] = 140.31280276817, }, [40] = {[50] = 283.19446366782, }, [50] = {[30] = 40.835986159169, }, [30] = {[51] = 57.074048442906, }, [51] = {[10] = 208.09965397924, }, }
All Newly Detected Tags:
4684074A  880D0201030102012302202031353030
B670074A  880D0101030102012302202031353030
cleanup() Complete at 972.20

Success compiling C:\trains\MTH\PC Control\Scripts\Tag DTO Distance Test.lua
setup()
Engine#13 P&LE GP7 #1500   PS3
TIU : 1
Accuracy Limit = 1.5%
Run Time = 0.10 Seconds
Run Time = 11.50 Seconds
Acc = 1 Dec = 1
setup : Set speed to 20
Waiting for RFID Tag Detection
(23.90s) Detector = 5 Reader = 0 DTO = 0.000 Seconds
(29.50s) Detector = 3 Reader = 0 DTO = 0.078 Smiles Delta DTO = 0.031 Smiles (41.057 inches)
   Inches   = 41.057         -          Expected Inches = 40.564 Error = 0.494 Inches (1.217%)
(37.20s) Detector = 5 Reader = 1 DTO = 0.121 Smiles Delta DTO = 0.043 Smiles (56.615 inches)
   Inches   = 56.615         -          Expected Inches = 56.647 Error = -0.033 Inches (-0.058%)
(65.60s) Detector = 1 Reader = 0 DTO = 0.278 Smiles Delta DTO = 0.157 Smiles (207.734 inches)
   Inches   = 207.734         -          Expected Inches = 207.289 Error = 0.445 Inches (0.215%)
(197.00s) Detector = 4 Reader = 1 DTO = 1.007 Smiles Delta DTO = 0.729 Smiles (962.181 inches)
   Inches   = 962.181         -          Expected Inches = 952.718 Error = 9.463 Inches (0.993%)
(217.20s) Detector = 2 Reader = 1 DTO = 1.118 Smiles Delta DTO = 0.112 Smiles (147.377 inches)
   Inches   = 147.377         -          Expected Inches = 146.693 Error = 0.684 Inches (0.466%)
(256.40s) Detector = 2 Reader = 0 DTO = 1.336 Smiles Delta DTO = 0.218 Smiles (287.142 inches)
   Inches   = 287.142         -          Expected Inches = 286.093 Error = 1.049 Inches (0.367%)
(275.50s) Detector = 4 Reader = 0 DTO = 1.442 Smiles Delta DTO = 0.106 Smiles (140.053 inches)
   Inches   = 140.053         -          Expected Inches = 139.805 Error = 0.248 Inches (0.177%)
(314.20s) Detector = 5 Reader = 0 DTO = 1.657 Smiles Delta DTO = 0.215 Smiles (283.194 inches)
   Inches   = 283.194         -          Expected Inches = 280.153 Error = 3.041 Inches (1.085%)
(319.80s) Detector = 3 Reader = 0 DTO = 1.688 Smiles Delta DTO = 0.031 Smiles (40.853 inches)
   Inches   = 40.853         -          Expected Inches = 40.564 Error = 0.289 Inches (0.712%)
(327.60s) Detector = 5 Reader = 1 DTO = 1.731 Smiles Delta DTO = 0.043 Smiles (57.080 inches)
   Inches   = 57.080         -          Expected Inches = 56.647 Error = 0.432 Inches (0.763%)
[STOP]

Success compiling C:\trains\MTH\PC Control\Scripts\Tag DTO Distance Test.lua
setup()
Engine#16 P&LE RS-3 #8356  PS3
TIU : 1
Accuracy Limit = 1.5%
Run Time = 0.10 Seconds
Run Time = 11.50 Seconds
Acc = 1 Dec = 1
setup : Set speed to 20
Waiting for RFID Tag Detection
(23.00s) Detector = 2 Reader = 1 DTO = 0.000 Seconds
(62.00s) Detector = 2 Reader = 0 DTO = 0.259 Smiles Delta DTO = 0.217 Smiles (286.310 inches)
   Inches   = 286.310         -          Expected Inches = 286.093 Error = 0.216 Inches (0.076%)
(81.10s) Detector = 4 Reader = 0 DTO = 0.365 Smiles Delta DTO = 0.106 Smiles (139.733 inches)
   Inches   = 139.733         -          Expected Inches = 139.805 Error = -0.072 Inches (-0.052%)
(119.30s) Detector = 5 Reader = 0 DTO = 0.577 Smiles Delta DTO = 0.212 Smiles (280.165 inches)
   Inches   = 280.165         -          Expected Inches = 280.153 Error = 0.011 Inches (0.004%)
(124.80s) Detector = 3 Reader = 0 DTO = 0.608 Smiles Delta DTO = 0.030 Smiles (40.104 inches)
   Inches   = 40.104         -          Expected Inches = 40.564 Error = -0.460 Inches (-1.135%)
(132.50s) Detector = 5 Reader = 1 DTO = 0.651 Smiles Delta DTO = 0.043 Smiles (56.659 inches)
   Inches   = 56.659         -          Expected Inches = 56.647 Error = 0.011 Inches (0.020%)
(160.70s) Detector = 1 Reader = 0 DTO = 0.807 Smiles Delta DTO = 0.157 Smiles (207.062 inches)
   Inches   = 207.062         -          Expected Inches = 207.289 Error = -0.227 Inches (-0.110%)
(290.70s) Detector = 4 Reader = 1 DTO = 1.529 Smiles Delta DTO = 0.722 Smiles (952.762 inches)
   Inches   = 952.762         -          Expected Inches = 952.718 Error = 0.044 Inches (0.005%)
(310.80s) Detector = 2 Reader = 1 DTO = 1.641 Smiles Delta DTO = 0.112 Smiles (147.375 inches)
   Inches   = 147.375         -          Expected Inches = 146.693 Error = 0.682 Inches (0.465%)
(349.70s) Detector = 2 Reader = 0 DTO = 1.858 Smiles Delta DTO = 0.217 Smiles (286.110 inches)
   Inches   = 286.110         -          Expected Inches = 286.093 Error = 0.017 Inches (0.006%)
(368.80s) Detector = 4 Reader = 0 DTO = 1.964 Smiles Delta DTO = 0.106 Smiles (139.933 inches)
   Inches   = 139.933         -          Expected Inches = 139.805 Error = 0.128 Inches (0.091%)
(407.10s) Detector = 5 Reader = 0 DTO = 2.176 Smiles Delta DTO = 0.212 Smiles (280.392 inches)
   Inches   = 280.392         -          Expected Inches = 280.153 Error = 0.238 Inches (0.085%)
(412.60s) Detector = 3 Reader = 0 DTO = 2.207 Smiles Delta DTO = 0.031 Smiles (40.320 inches)
   Inches   = 40.320         -          Expected Inches = 40.564 Error = -0.244 Inches (-0.602%)
(420.20s) Detector = 5 Reader = 1 DTO = 2.249 Smiles Delta DTO = 0.042 Smiles (56.010 inches)
   Inches   = 56.010         -          Expected Inches = 56.647 Error = -0.638 Inches (-1.126%)
(448.50s) Detector = 1 Reader = 0 DTO = 2.406 Smiles Delta DTO = 0.157 Smiles (207.683 inches)
   Inches   = 207.683         -          Expected Inches = 207.289 Error = 0.394 Inches (0.190%)
(578.40s) Detector = 4 Reader = 1 DTO = 3.128 Smiles Delta DTO = 0.721 Smiles (952.119 inches)
   Inches   = 952.119         -          Expected Inches = 952.718 Error = -0.599 Inches (-0.063%)
(598.50s) Detector = 2 Reader = 1 DTO = 3.239 Smiles Delta DTO = 0.112 Smiles (147.370 inches)
   Inches   = 147.370         -          Expected Inches = 146.693 Error = 0.677 Inches (0.461%)
[STOP]
Run Time = 638.80 Seconds
Trip Odometer Finish 3.41 Smiles
{[21] = {[20] = 286.3095623238, }, [20] = {[40] = 139.73286499977, }, [40] = {[50] = 280.16453297592, }, [50] = {[30] = 40.103526366872, }, [30] = {[51] = 56.658501640708, }, [51] = {[10] = 207.06197716874, }, [10] = {[41] = 952.7623977446, }, [41] = {[21] = 147.37532929704, }, [21] = {[20] = 286.10990433055, }, [20] = {[40] = 139.93252299302, }, [40] = {[50] = 280.39192124601, }, [50] = {[30] = 40.319822526228, }, [30] = {[51] = 56.009613162638, }, [51] = {[10] = 207.68313536997, }, [10] = {[41] = 952.1190553219, }, [41] = {[21] = 147.36978324167, }, }
All Newly Detected Tags:
B62E144A  8810020103010D012302202038333536
E63F1A4A  8810010103010D012302202038333536
cleanup() Complete at 638.80

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