using System; using System.Text; namespace SWModules { public class Utils { public static int getField(byte[] inBytes, byte token, int desiredField, ref byte[] returnField) { int currentField = 0; int returnFieldIndex = 0; bool inDesiredField; //TODO P2 I don't think we need this block and it doesn't look like returnFieldIndex means anything if (desiredField == 0) inDesiredField = true; else inDesiredField = false; Array.Clear(returnField, 0, returnField.Length); for (int i = 0; i < inBytes.Length; i++) { if ((inBytes[i] == token) && !inDesiredField) currentField++; else if (currentField == desiredField) { inDesiredField = true; if ((inBytes[i] == token) || (inBytes[i] == 10) || (inBytes[i] == 13)) return (returnFieldIndex); returnField[returnFieldIndex++] = inBytes[i]; if (returnFieldIndex >= returnField.Length) return returnFieldIndex; } } return (0); } public static int getField(StringBuilder inSB, char token, int desiredField, ref StringBuilder returnField) { int currentField = 0; int returnFieldIndex = 0; bool inDesiredField; //TODO P2 I don't think we need this block and it doesn't look like returnFieldIndex means anything if (desiredField == 0) inDesiredField = true; else inDesiredField = false; returnField.Clear(); for (int i = 0; i < inSB.Length; i++) { if ((inSB[i] == token) && !inDesiredField) currentField++; else if (currentField == desiredField) { inDesiredField = true; if ((inSB[i] == token) || (inSB[i] == 10) || (inSB[i] == 13)) return (returnFieldIndex); returnField.Append(inSB[i]); if (returnFieldIndex >= returnField.Length) return returnFieldIndex; } } return (0); } /// /// Compares values in sequence for two byte arrays, and returns true if A = B for the subset that is identified. /// /// Input Array to check /// Array offset to start comparison in A /// Second input array to check /// Array offset for second input /// Number of bytes to compare /// public static bool CompareArray(byte[] aBytes, int aOffset, byte[] bBytes, int bOffset, int count) { if ((aBytes.Length < aOffset+count)||(bBytes.Length < bOffset+count)) return false; for (int i = 0; i < count; i++) { if (aBytes[i + aOffset] != bBytes[bOffset + i]) return false; } return true; } public static uint SecondsSinceEpoch { get { TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1); return (uint)(t.Seconds + t.Minutes * 60 + t.Hours * 3600 + t.Days * 86400); } } public static uint dateTimeToPosixTime(DateTime timeNow) { TimeSpan t = timeNow - new DateTime(1970, 1, 1); return (uint)(t.Seconds + t.Minutes * 60 + t.Hours * 3600 + t.Days * 86400); } } public enum WfrState { Waiting = 0, GotResponse = 1, NotWaiting = -2, TimedOut = -1, } } //From the old todo.cs file //TODO P1 See if the logic to dumpCPData is right, might need to rework booleans so there is a flag that goes true if we actually get into CP mode //TODO P1 check if float is at surface for example: //if (ctd.SBE41LPF.Pressure< (configFile.cpPressureCutoff + 0.5)) //{ // //is CTD in CP mode, and will data need to be dumped? // if (configFile.CPMode) // { // DumpCPData = true; // return (Program.CPFStates.initProfile); // } // return (Program.CPFStates.initProfile); //TODO P2 Implement watchdog functionality //TODO P2 Add qS.ErrorCode everywhere and handle like SBE41. //TODO P2 All commands sent to devices should log themselves //TODO P2 Add messageIndex check in all IO drivers to make sure we don't spin off the end of the messageBytes array. Link it to Queue width //TODO P2 Add error checking to Elmo read and writes //TODO P2 Add Elmo monitor functions //TODO P2 Deal with failure in initMission actions like checkValveAction //TODO P2 Be sure to test pressure tables with multiple park stations //TODO P2 Reduce verbosity level in recovery mode //TODO P2 Make verbosity level functional //TODO P2 Make sure all .Parse methods work on char array not byte array with 0 elements after the value //TODO P2 Should setPV set SV.RunPID true? //TODO P2 Investigate why 1 Hz CTD data is noiser than .3 Hz data //TODO P2 Deal with extend/retract bellows return(false) condition //TODO P2 make sure ascend will find the surface even if SBE41 doesn't e.g. look for GPS signal above 10 meters or something like that //TODO P2 Make SV.checkStruckPressure = true in basicStateEntry and make false where needed //TODO P2 Deal with all checkForResponse return codes instead of assuming everything worked //TODO P2 Probably should re-work descend and ascend so it doesn't call setPV if it isn't a park station //TODO P2 Use checkBellowsPosition outside limits as test case for how to structure error repsonse. Example, detecting an outside limits condition should prevent any further motion in that directin by any method or state //TODO P2 Change create standard mission to allows park time to be passed in as a parameter //TODO P2 Deal with the issue in the 4th line down //$ 10-Nov-2015 10:23:54.280 Dump CP Data Unparsed SBE41 Message 8.90, 19.6494, 34.7218 //$ 10-Nov-2015 11:48:38.953 Dump CP Data RecMode false, PID Off, Stopped, Scend sub: Outside Band, depthNum = 0 2.170000 63.304885 29.875000 0.185000 -100.000000 //$ 10-Nov-2015 11:48:41.785 Dump CP Data Didn't get dd response, restarting command timer //$ 10-Nov-2015 11:48:41.784 Dump CP Data Unparsed SBE41 Message SBE41 waitingForResponse expended all retries //$ 10-Nov-2015 11:48:42.191 Dump CP Data RecMode false, PID Off, Stopped, Scend sub: Outside Band, depthNum = 0 2.170000 63.305910 29.875000 0.195000 -100.000000 //$ 10-Nov-2015 11:48:44.831 Dump CP Data Unparsed SBE41 Message S> //$ 10-Nov-2015 10:23:57.211 Dump CP Data Unparsed SBE41 Message 8.89, 19.6493, 34.7219 //$ 10-Nov-2015 11:48:46.033 Dump CP Data Normal state exit //$ 10-Nov-2015 11:48:46.144 Dump CP Data RecMode false, PID Off, Stopped, Scend sub: Outside Band, depthNum = 0 2.170000 63.305910 29.875000 0.195000 -100.000000 //$ 10-Nov-2015 11:48:47.865 Surface Ops State Entry //$ 10-Nov-2015 11:48:48.478 Surface Ops Closing old engr log file: \SD\2015-11-10T11-13-59