This commit is contained in:
2025-09-16 10:42:51 +01:00
parent 50bb9c9781
commit 0c463ad929
8 changed files with 351 additions and 200 deletions

View File

@@ -183,7 +183,7 @@ namespace AiQ_GUI
}
await Wait; // Finished to 5s wait
await SetTrim(); // Auto trims the cameras, some plates should have been captured in the meantime
await FlexiAPI.SetTrim(CamOnTest.IP, LblTestTubePing.Text); // Auto trims the cameras, some plates should have been captured in the meantime
if (!await FlexiAPI.ZoomModules("0000", CamOnTest.IP)) // Zoom to full wide
await TestFailed(BtnStartTest, "Could not zoom modules to full wide");
@@ -686,81 +686,6 @@ namespace AiQ_GUI
Printer.PrintSerialLbl(CamOnTest.Model, NewSerial, CameraAccessInfo.Processor); // Print model/serial label
}
private async Task SetTrim(int RetryCount = 0) // Sets trim by getting plate postion as metric
{
Trim trim;
string trimData = await FlexiAPI.APIHTTPRequest("/SightingCreator-plate-positions", CamOnTest.IP, 5); // Get plate positions
try // Deserialise the JSON
{
Logging.LogMessage("Trim Data: " + trimData);
trim = JsonConvert.DeserializeObject<Trim>(trimData);
}
catch
{
await TestFailed(BtnStartTest, "Error reading JSON - " + trimData);
return;
}
// Check no value is -1 (no plate found) or if the positions are identical (one plate found). If it is then try again 3 times
if (new[] { trim.infraredX, trim.infraredY, trim.colourX, trim.colourY }.Any(value => value == -1)
|| (trim.infraredX == trim.colourX && trim.infraredY == trim.colourY))
{
if (RetryCount >= 3)
{
await DisplayOK("Please align trim in webpage then click OK."); // Awaited till OK has been clicked
return;
}
await Task.Delay(5000); // Give 5 second delay for it to see a plate
await SetTrim(RetryCount++);
}
int offset = 105;
if (LblTestTubePing.Text == "❌") // Test tube not connected so do the 2.7m check.
offset = 98;
// Horizontal distance offset for 2.7m compared to 30m is 98 pixels. This was empirically found from testing in the car park
// Colour camera is to the right of the infrared so it gets the offset.
// Using similar triangles going from 2.7m -> 0.65m which is the length of the test tube (Also exactly 1/4 length).
// 98 * (29.35/27.3) = 105.35 pixels
int OverviewX = trim.colourX + offset;
if (OverviewX > 1920) // If adding on the offset has pushed it out of limits then remove 0.1
{
if (OverviewX < 2120 && trim.infraredX > 400) // Within enough of a limit to automatically do it
{
OverviewX -= 200;
trim.infraredX -= 200;
}
else // Ask user to centre the plate in the field of view
{
await DisplayOK("Please centralise plate in view THEN press OK"); // Awaited till OK has been clicked
if (RetryCount >= 3)
{
await DisplayOK("Please align trim in webpage then click OK."); // Awaited till OK has been clicked
return;
}
await Task.Delay(5000); // Give 5 second delay for it to see a plate
await SetTrim(RetryCount++);
}
}
// Compensated trim values, therefore should be close to 0,0 with limits of ±5% of 1920 and 1080 respectivly being ±96 and ±54
int TrimX = trim.infraredX - OverviewX;
int TrimY = trim.infraredY - trim.colourY;
// Update trim values
string[,] Trim_JSON = { { "propInterCameraOffsetX", Convert.ToString(TrimX) }, { "propInterCameraOffsetY", Convert.ToString(TrimY) } };
string TrimResp = await FlexiAPI.HTTP_Update("SightingCreator", CamOnTest.IP, Trim_JSON);
AddToActionsList(TrimResp, false);
if (!TrimResp.Contains($"\"propInterCameraOffsetX\": {{\"value\": \"{Convert.ToString(TrimX)}\", \"datatype\": \"int\"}}, \"propInterCameraOffsetY\": {{\"value\": \"{Convert.ToString(TrimY)}\", \"datatype\": \"int\"}},"))
AddToActionsList("Could not set camera trim");
}
// ***** Top right buttons *****
private void BtnClose_Click(object sender, EventArgs e)
{
@@ -800,7 +725,8 @@ namespace AiQ_GUI
private async void BtnFindCams_Click(object sender, EventArgs e)
{
CbBxFoundCams.Text = "Searching";
BtnFindCams.Enabled = BtnSetAll211.Enabled = BtnSoak.Enabled = BtnSet211.Enabled = BtnSetGodMode.Enabled = BtnUploadBlob.Enabled = SetGodModeAll.Enabled = false;
BtnFindCams.Enabled = BtnSetAll211.Enabled = BtnSoak.Enabled = BtnSet211.Enabled = BtnSetGodMode.Enabled = BtnUploadBlob.Enabled = SetGodModeAll.Enabled = BtnFactoryDefault.Enabled = false;
BtnSetGodMode.BackColor = BtnUploadBlob.BackColor = BtnFactoryDefault.BackColor = BtnSetAll211.BackColor = BtnColour;
CbBxFoundCams.Items.Clear();
soakCameraList.Clear();
@@ -838,7 +764,7 @@ namespace AiQ_GUI
int cameraCount = CbBxFoundCams.Items.Count;
CbBxFoundCams.Text = cameraCount > 0 ? $"{cameraCount} Camera{(cameraCount == 1 ? "" : "s")} Found" : "No Cameras Found";
BtnFindCams.Enabled = BtnSetAll211.Enabled = SetGodModeAll.Enabled = BtnSoak.Enabled = BtnUploadBlob.Enabled = true;
BtnFindCams.Enabled = BtnSetAll211.Enabled = SetGodModeAll.Enabled = BtnSoak.Enabled = BtnUploadBlob.Enabled = BtnFactoryDefault.Enabled = true;
}
private void BtnYes_Click(object sender, EventArgs e)
@@ -947,6 +873,7 @@ namespace AiQ_GUI
private async void BtnSetGodMode_Click(object sender, EventArgs e)
{
BtnSetGodMode.BackColor = BtnColour;
bool isGodModeCurrentlyOn = BtnSetGodMode.Text.Contains("On");
string newGodModeValue = isGodModeCurrentlyOn ? "true" : "false";
string[,] GOD_JSON = { { "propGodMode", newGodModeValue } };
@@ -954,13 +881,8 @@ namespace AiQ_GUI
try
{
await FlexiAPI.HTTP_Update("Internal Config", CamOnTest.IP, GOD_JSON);
BtnSetGodMode.Text = newGodModeValue == "true" ? "Set God Mode Off" : "Set God Mode On";
Color originalColor = BtnSetGodMode.BackColor;
BtnSetGodMode.BackColor = Color.Green;
await Task.Delay(500);
BtnSetGodMode.BackColor = originalColor;
}
catch (Exception ex)
{
@@ -1663,6 +1585,7 @@ namespace AiQ_GUI
private async void BtnUploadBlob_Click(object sender, EventArgs e)
{
BtnUploadBlob.BackColor = BtnColour;
const string networkFolderPath = @"G:\Shared drives\MAV Production\MAV_146_AiQ_Mk2\Flexi";
string fileToUpload = null;
@@ -1716,10 +1639,13 @@ namespace AiQ_GUI
AddToActionsList($"Upload result for {cam.IP}: {result}", false);
await Task.Delay(500);
}
BtnUploadBlob.BackColor = Color.Green;
}
private async void BtnFactoryDefault_Click(object sender, EventArgs e)
{
BtnFactoryDefault.BackColor = BtnColour;
foreach (Camera SCL in soakCameraList) // Reset all cameras that were being soaked to default module settings
{
if (!SCL.IsChecked)
@@ -1728,116 +1654,70 @@ namespace AiQ_GUI
Network.Initialize("developer", SCL.DevPass); // Ensure network is initialized to the right camera, cannot be done in soak test finally becuase of this.
await CameraModules.FactoryResetModules(SCL.IP);
}
BtnFactoryDefault.BackColor = Color.Green;
}
private async void SwitchTest(string TestingType)
// Constants
const double RealPlateWidthMeters = 0.52; // UK standard plate width
const double FocalLengthPixels = (50 * 1280) / 14.111224; // focal mm * pixel width / sensor width for IQ
// const double FocalLengthPixels = (50 * 1920) / 6.95; // focal mm * pixel width / sensor width for AiQ
const double FrameRate = 25.0; // Frames per second
public class FrameData
{
object sender = new();
EventArgs e = new();
Properties.Settings.Default.UnitTesting = TestingType;
Properties.Settings.Default.Save();
CAMTYPE CAMTYPE = TestingType.Substring(0, TestingType.IndexOf('_')) switch
{
"GOOD" => CAMTYPE.GOOD,
"BAD" => CAMTYPE.BAD,
"BIZARRE" => CAMTYPE.BIZARRE,
_ => CAMTYPE.GOOD,
};
FakeCamera fakeCamera = new(80); // Create an instance of FakeCamera
_ = fakeCamera.StartAsync(CAMTYPE).ContinueWith(task =>
{
if (task.IsFaulted)
AddToActionsList("Error starting FakeCamera: " + task.Exception?.Message);
else
AddToActionsList($"FakeCamera started successfully. IP: {fakeCamera}", false);
});
await Task.Delay(5000); // Wait for server to start
CbBxFoundCams.Text = "localhost"; // Should force update in creds an network reinit
CbBxFoundCams_SelectedIndexChanged(sender, e);
CbBxCameraType.SelectedIndex = CbBxCameraType.Items.Count - 1; // Selects AB12CD as model number
while(TxBxOutput.Text.Length < 2) // Wait for developer password to be generated
await Task.Delay(1000);
if (TestingType.Contains("FINAL"))
BtnStartTest_Click(sender, e); // Run final test
else if (TestingType.Contains("PRE"))
BtnPreTest_Click(sender, e); // Run pre-test
fakeCamera.Stop(); // Stop the server
public long FrameID;
public int PlatePosX;
public int PlatePosY;
public int PlateWidthPixels;
}
public double EstimateSpeed(List<FrameData> frames)
{
double TimeElapsed = 0;
int frameCount = frames.Count;
for (int i = 1; i < frameCount; i++)
{
double time = (frames[i].FrameID - frames[i - 1].FrameID) / FrameRate;
TimeElapsed += time;
}
double FarDist = (FocalLengthPixels * RealPlateWidthMeters) / frames[0].PlateWidthPixels;
double CloseDist = (FocalLengthPixels * RealPlateWidthMeters) / frames[frameCount - 1].PlateWidthPixels;
double speedMph = (Math.Abs(FarDist - CloseDist) / TimeElapsed) * 2.237;
return speedMph;
}
// ***** Test & Debug *****
private void BtnTest_Click(object sender, EventArgs e)
{
Stopwatch stopWatchTest = Stopwatch.StartNew();
// *** To be put in startup code!!!! ***
if (Properties.Settings.Default.UnitTesting != "NOT_STARTED")
BtnTest_Click(sender, e);
// *** TO be put in test button ***
if (Properties.Settings.Default.UnitTesting == "NOT_STARTED")
List<FrameData> frames = new List<FrameData>
{
SwitchTest("GOOD_PRE");
new FrameData { FrameID = 60192555, PlatePosX = 1172, PlatePosY = 393, PlateWidthPixels = 108 },
new FrameData { FrameID = 60192556, PlatePosX = 1103, PlatePosY = 361, PlateWidthPixels = 105 },
new FrameData { FrameID = 60192558, PlatePosX = 983, PlatePosY = 331, PlateWidthPixels = 99 },
new FrameData { FrameID = 60192559, PlatePosX = 930, PlatePosY = 301, PlateWidthPixels = 95 },
new FrameData { FrameID = 60192560, PlatePosX = 880, PlatePosY = 304, PlateWidthPixels = 93 },
new FrameData { FrameID = 60192561, PlatePosX = 834, PlatePosY = 278, PlateWidthPixels = 89 },
new FrameData { FrameID = 60192562, PlatePosX = 792, PlatePosY = 229, PlateWidthPixels = 87 },
new FrameData { FrameID = 60192563, PlatePosX = 752, PlatePosY = 208, PlateWidthPixels = 85 },
new FrameData { FrameID = 60192565, PlatePosX = 680, PlatePosY = 187, PlateWidthPixels = 81 },
new FrameData { FrameID = 60192566, PlatePosX = 648, PlatePosY = 167, PlateWidthPixels = 78 },
new FrameData { FrameID = 60192567, PlatePosX = 617, PlatePosY = 149, PlateWidthPixels = 76 },
new FrameData { FrameID = 60192568, PlatePosX = 588, PlatePosY = 132, PlateWidthPixels = 75 },
new FrameData { FrameID = 60192569, PlatePosX = 561, PlatePosY = 100, PlateWidthPixels = 70 },
new FrameData { FrameID = 60192570, PlatePosX = 535, PlatePosY = 85, PlateWidthPixels = 72 },
new FrameData { FrameID = 60192572, PlatePosX = 488, PlatePosY = 70, PlateWidthPixels = 69 },
new FrameData { FrameID = 60192573, PlatePosX = 466, PlatePosY = 55, PlateWidthPixels = 67 }
};
// Run Good pre test
// Check it was the correct outcome
// Restart GUI
}
else if (Properties.Settings.Default.UnitTesting == "GOOD_PRE")
{
SwitchTest("GOOD_FINAL");
// Run Good final test
// Check it was the correct outcome
// Restart GUI
}
else if (Properties.Settings.Default.UnitTesting == "GOOD_FINAL")
{
SwitchTest("BAD_PRE");
// Run Bad pre test
// Check it was the correct outcome
// Restart GUI
}
// etc...
//// SSH testing
//sshData = SSH.CollectSSHData("localhost");
//AddToActionsList(sshData.packages);
//AddToActionsList(sshData.FilesystemSize);
//AddToActionsList($"{sshData.tailscale}");
//// Functionality testing
//// TODO - SSH server needs to be running at this point for this to work
//var server = new FakeCamera(80); // Start the HTTP server in a background task
//_ = server.StartAsync(CAMTYPE.GOOD); // Start the server running with correct responses
//Task.Delay(1000).Wait(); // Wait for server to start
//CbBxCameraType.SelectedIndex = CbBxCameraType.Items.Count - 1; // Selects AB12CD as model number
//CbBxFoundCams.Text = "localhost"; // Should force update in creds an network reinit
//BtnPreTest_Click(sender, e); // Run pre-test
//BtnStartTest_Click(sender, e); // Run full test
//server.Stop(); // Stop the server
//_ = server.StartAsync(CAMTYPE.BAD); // Start the server running with bad responses
//Task.Delay(1000).Wait(); // Wait for server to start
//BtnPreTest_Click(sender, e); // Run pre-test
//BtnStartTest_Click(sender, e); // Run full test
//server.Stop(); // Stop the server
//_ = server.StartAsync(CAMTYPE.BIZARRE); // Start the server running with incorrect types and odd responses
//Task.Delay(1000).Wait(); // Wait for server to start
//BtnPreTest_Click(sender, e); // Run pre-test
//BtnStartTest_Click(sender, e); // Run full test
//server.Stop(); // Stop the server
double Spd = EstimateSpeed(frames);
AddToActionsList("Estimated Speed: " + Spd.ToString("F2") + " MPH");
stopWatchTest.Stop();
AddToActionsList("RunTime " + stopWatchTest.Elapsed.ToString(@"hh\:mm\:ss\.ff"));