< Summary

Class:SimMonitor
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/Monitor.cs
Covered lines:45
Uncovered lines:124
Coverable lines:169
Total lines:255
Line coverage:26.6% (45 of 169)
Covered branches:0
Total branches:0
Covered methods:8
Total methods:20
Method coverage:40% (8 of 20)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Awake()0%110100%
Start()0%110100%
InitializeSessionDirectory()0%110100%
InitializeTelemetryLogFiles()0%2100%
InitializeEventLogFiles()0%110100%
CloseTelemetryLogFiles()0%12300%
MonitorRoutine()0%12300%
RecordTelemetry()0%56700%
ConvertBinaryTelemetryToCsv(...)0%56700%
WriteEventsToFile()0%12300%
RegisterSimulationStarted()0%3.433063.64%
RegisterSimulationEnded()0%12300%
ConvertBinaryTelemetryToCsvCoroutine()0%12300%
RegisterNewThreat(...)0%220100%
RegisterNewInterceptor(...)0%220100%
RegisterNewAgent(...)0%110100%
RegisterInterceptorHit(...)0%6200%
RegisterInterceptorMiss(...)0%6200%
RegisterInterceptorEvent(...)0%12300%
OnDestroy()0%2100%

File(s)

/github/workspace/Assets/Scripts/Monitor.cs

#LineLine coverage
 1using UnityEngine;
 2using System.Collections;
 3using System.IO;
 4using System;
 5using System.Linq;
 6using System.Collections.Generic;
 7using System.Threading;
 8
 9public class SimMonitor : MonoBehaviour {
 10  private const float _updateRate = 0.1f;  // 100 Hz
 11  private string _telemetryBinPath;
 12  private string _eventLogPath;
 13  private Coroutine _monitorRoutine;
 14
 15  private string _sessionDirectory;
 16
 17  private FileStream _telemetryFileStream;
 18  private BinaryWriter _telemetryBinaryWriter;
 19
 20  [SerializeField]
 21  private List<EventRecord> _eventLogCache;
 22
 23  [System.Serializable]
 24  private class EventRecord {
 25    public float Time;
 26    public float PositionX;
 27    public float PositionY;
 28    public float PositionZ;
 29    public string EventType;
 30    public string Details;
 31  }
 32
 133  private void Awake() {
 134    InitializeSessionDirectory();
 135  }
 36
 137  private void Start() {
 138    SimManager.Instance.OnSimulationStarted += RegisterSimulationStarted;
 139    SimManager.Instance.OnSimulationEnded += RegisterSimulationEnded;
 140    SimManager.Instance.OnNewThreat += RegisterNewThreat;
 141    SimManager.Instance.OnNewInterceptor += RegisterNewInterceptor;
 142  }
 43
 144  private void InitializeSessionDirectory() {
 145    string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
 146    _sessionDirectory = Application.persistentDataPath + $"\\Telemetry\\Logs\\{timestamp}";
 147    Directory.CreateDirectory(_sessionDirectory);
 148    Debug.Log($"Monitoring simulation logs to {_sessionDirectory}");
 149  }
 50
 051  private void InitializeTelemetryLogFiles() {
 052    string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
 053    _telemetryBinPath = Path.Combine(_sessionDirectory, $"sim_telemetry_{timestamp}.bin");
 54
 55    // Open the file stream and binary writer for telemetry data
 056    _telemetryFileStream =
 57        new FileStream(_telemetryBinPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
 058    _telemetryBinaryWriter = new BinaryWriter(_telemetryFileStream);
 59
 060    Debug.Log("Telemetry log file initialized successfully.");
 061  }
 62
 263  private void InitializeEventLogFiles() {
 264    string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
 265    _eventLogPath = Path.Combine(_sessionDirectory, $"sim_events_{timestamp}.csv");
 66
 67    // Initialize the event log cache
 268    _eventLogCache = new List<EventRecord>();
 69
 270    Debug.Log("Event log file initialized successfully.");
 271  }
 72
 073  private void CloseTelemetryLogFiles() {
 074    if (_telemetryBinaryWriter != null) {
 075      _telemetryBinaryWriter.Flush();
 076      _telemetryBinaryWriter.Close();
 077      _telemetryBinaryWriter = null;
 078    }
 79
 080    if (_telemetryFileStream != null) {
 081      _telemetryFileStream.Close();
 082      _telemetryFileStream = null;
 083    }
 084  }
 85
 086  private IEnumerator MonitorRoutine() {
 087    while (true) {
 088      RecordTelemetry();
 089      yield return new WaitForSeconds(_updateRate);
 090    }
 91  }
 92
 093  private void RecordTelemetry() {
 094    float time = (float)SimManager.Instance.GetElapsedSimulationTime();
 095    var agents = SimManager.Instance.GetActiveAgents();
 096    if (_telemetryBinaryWriter == null) {
 097      Debug.LogWarning("Telemetry binary writer is null");
 098      return;
 99    }
 0100    for (int i = 0; i < agents.Count; i++) {
 0101      var agent = agents[i];
 102
 0103      if (!agent.gameObject.activeInHierarchy)
 0104        continue;
 105
 0106      Vector3 pos = agent.transform.position;
 107
 0108      if (pos == Vector3.zero)
 0109        continue;
 110
 0111      Vector3 vel = agent.GetVelocity();  // Ensure GetVelocity() doesn't allocate
 112
 0113      int agentID = agent.GetInstanceID();
 0114      int flightPhase = (int)agent.GetFlightPhase();
 0115      byte agentType = (byte)(agent is Threat ? 0 : 1);
 116
 117      // Write telemetry data directly to the binary file
 0118      _telemetryBinaryWriter.Write(time);
 0119      _telemetryBinaryWriter.Write(agentID);
 0120      _telemetryBinaryWriter.Write(pos.x);
 0121      _telemetryBinaryWriter.Write(pos.y);
 0122      _telemetryBinaryWriter.Write(pos.z);
 0123      _telemetryBinaryWriter.Write(vel.x);
 0124      _telemetryBinaryWriter.Write(vel.y);
 0125      _telemetryBinaryWriter.Write(vel.z);
 0126      _telemetryBinaryWriter.Write(flightPhase);
 0127      _telemetryBinaryWriter.Write(agentType);
 0128    }
 0129  }
 130
 0131  public void ConvertBinaryTelemetryToCsv(string binaryFilePath, string csvFilePath) {
 0132    try {
 0133      using FileStream fs =
 134          new FileStream(binaryFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
 0135      using BinaryReader reader = new BinaryReader(fs);
 0136      using StreamWriter writer = new StreamWriter(csvFilePath, false);
 0137      {
 138        // Write CSV header
 0139        writer.WriteLine(
 140            "Time,AgentID,AgentX,AgentY,AgentZ,AgentVX,AgentVY,AgentVZ,AgentState,AgentType");
 141
 0142        while (reader.BaseStream.Position != reader.BaseStream.Length) {
 0143          float time = reader.ReadSingle();
 0144          int agentID = reader.ReadInt32();
 0145          float posX = reader.ReadSingle();
 0146          float posY = reader.ReadSingle();
 0147          float posZ = reader.ReadSingle();
 0148          float velX = reader.ReadSingle();
 0149          float velY = reader.ReadSingle();
 0150          float velZ = reader.ReadSingle();
 0151          int flightPhase = reader.ReadInt32();
 0152          byte agentTypeByte = reader.ReadByte();
 0153          string agentType = agentTypeByte == 0 ? "T" : "M";
 154
 155          // Write the data to CSV
 0156          writer.WriteLine(
 157              $"{time:F2},{agentID},{posX:F2},{posY:F2},{posZ:F2},{velX:F2},{velY:F2},{velZ:F2},{flightPhase},{agentType
 0158        }
 0159      }
 0160    } catch (IOException e) {
 0161      Debug.LogWarning(
 162          $"An IO error occurred while converting binary telemetry to CSV: {e.Message}");
 0163    }
 0164  }
 165
 0166  private void WriteEventsToFile() {
 0167    using (StreamWriter writer = new StreamWriter(_eventLogPath, false)) {
 168      // Write CSV header
 0169      writer.WriteLine("Time,PositionX,PositionY,PositionZ,Event,Details");
 170
 0171      foreach (var record in _eventLogCache) {
 0172        writer.WriteLine(
 173            $"{record.Time:F2},{record.PositionX:F2},{record.PositionY:F2},{record.PositionZ:F2},{record.EventType},{rec
 0174      }
 0175    }
 0176  }
 177
 2178  private void RegisterSimulationStarted() {
 2179    if (SimManager.Instance.simulatorConfig.enableTelemetryLogging) {
 0180      InitializeTelemetryLogFiles();
 0181      _monitorRoutine = StartCoroutine(MonitorRoutine());
 0182    }
 4183    if (SimManager.Instance.simulatorConfig.enableEventLogging) {
 2184      InitializeEventLogFiles();
 2185    }
 2186  }
 187
 0188  private void RegisterSimulationEnded() {
 0189    if (SimManager.Instance.simulatorConfig.enableTelemetryLogging) {
 0190      StopCoroutine(_monitorRoutine);
 0191      CloseTelemetryLogFiles();
 0192      StartCoroutine(ConvertBinaryTelemetryToCsvCoroutine(
 193          _telemetryBinPath, Path.ChangeExtension(_telemetryBinPath, ".csv")));
 0194    }
 0195    if (SimManager.Instance.simulatorConfig.enableEventLogging) {
 0196      WriteEventsToFile();
 0197    }
 0198  }
 199
 200  private IEnumerator ConvertBinaryTelemetryToCsvCoroutine(string binaryFilePath,
 0201                                                           string csvFilePath) {
 0202    yield return null;  // Wait for the next frame to ensure RecordTelemetry() has finished
 0203    ConvertBinaryTelemetryToCsv(binaryFilePath, csvFilePath);
 0204  }
 205
 7206  public void RegisterNewThreat(Threat threat) {
 14207    if (SimManager.Instance.simulatorConfig.enableEventLogging) {
 7208      RegisterNewAgent(threat, "NEW_THREAT");
 7209    }
 7210  }
 211
 1212  public void RegisterNewInterceptor(Interceptor interceptor) {
 2213    if (SimManager.Instance.simulatorConfig.enableEventLogging) {
 1214      RegisterNewAgent(interceptor, "NEW_INTERCEPTOR");
 1215      interceptor.OnInterceptMiss += RegisterInterceptorMiss;
 1216      interceptor.OnInterceptHit += RegisterInterceptorHit;
 1217    }
 1218  }
 219
 8220  private void RegisterNewAgent(Agent agent, string eventType) {
 8221    float time = (float)SimManager.Instance.GetElapsedSimulationTime();
 8222    Vector3 pos = agent.transform.position;
 8223    var record = new EventRecord { Time = time,       PositionX = pos.x,     PositionY = pos.y,
 224                                   PositionZ = pos.z, EventType = eventType, Details = agent.name };
 8225    _eventLogCache.Add(record);
 8226  }
 227
 0228  public void RegisterInterceptorHit(Interceptor interceptor, Threat threat) {
 0229    if (SimManager.Instance.simulatorConfig.enableEventLogging) {
 0230      RegisterInterceptorEvent(interceptor, threat, true);
 0231    }
 0232  }
 233
 0234  public void RegisterInterceptorMiss(Interceptor interceptor, Threat threat) {
 0235    if (SimManager.Instance.simulatorConfig.enableEventLogging) {
 0236      RegisterInterceptorEvent(interceptor, threat, false);
 0237    }
 0238  }
 239
 0240  public void RegisterInterceptorEvent(Interceptor interceptor, Threat threat, bool hit) {
 0241    float time = (float)SimManager.Instance.GetElapsedSimulationTime();
 0242    Vector3 pos = interceptor.transform.position;
 0243    string eventType = hit ? "INTERCEPTOR_HIT" : "INTERCEPTOR_MISS";
 0244    var record = new EventRecord {
 245      Time = time,       PositionX = pos.x,     PositionY = pos.y,
 246      PositionZ = pos.z, EventType = eventType, Details = $"{interceptor.name} and {threat.name}"
 247    };
 0248    _eventLogCache.Add(record);
 0249  }
 250
 0251  private void OnDestroy() {
 0252    CloseTelemetryLogFiles();
 0253    WriteEventsToFile();
 0254  }
 255}