I have to prepare Logger class which will be saving data from 3 structs in interval of 10-15 ms. My approach to this problem is below:
public class Logger
{
// Variables
private Task loggerTask;
public bool IsActive { get; set; }
// Constructor
public Logger()
{
}
private void Logging()
{
#if DEBUG
System.Diagnostics.Debug.WriteLine("Logging has been started.");
#endif
FileStream fs = new FileStream($"./log {DateTime.Now.ToString("dd.MM HH.mm.ss")}.txt", FileMode.Create, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs, Encoding.Default);
try
{
Queue<double> times = new Queue<double>();
Queue<Attitude> attitudes = new Queue<Attitude>();
Queue<LocalPositionNed> positions = new Queue<LocalPositionNed>();
Queue<SetPositionTargetLocalNed> setpoints = new Queue<SetPositionTargetLocalNed>();
// Logs data
DateTime start = DateTime.Now;
DateTime last = start;
DateTime now;
while (IsActive)
{
now = DateTime.Now;
if ((now - last).TotalMilliseconds < 16)
continue;
last = now;
times.Enqueue((now - start).TotalMilliseconds);
attitudes.Enqueue(GCS.Instance.Drone.Attitude);
positions.Enqueue(GCS.Instance.Drone.LocalPositionNed);
setpoints.Enqueue(GCS.Instance.Offboard.SetPoint);
}
// Save data
for(int i = 0; i < times.Count; i++)
{
sw.WriteLine($"{times.ElementAt(i)}\t" +
$"{attitudes.ElementAt(i).Pitch}\t" +
$"{attitudes.ElementAt(i).Roll}\t" +
$"{attitudes.ElementAt(i).Yaw}\t" +
$"{attitudes.ElementAt(i).Pitchspeed}\t" +
$"{attitudes.ElementAt(i).Rollspeed}\t" +
$"{attitudes.ElementAt(i).Yawspeed}\t" +
$"{positions.ElementAt(i).X}\t" +
$"{positions.ElementAt(i).Y}\t" +
$"{positions.ElementAt(i).Z}\t" +
$"{positions.ElementAt(i).Vx}\t" +
$"{positions.ElementAt(i).Vy}\t" +
$"{positions.ElementAt(i).Vz}\t" +
$"{setpoints.ElementAt(i).Vx}\t" +
$"{setpoints.ElementAt(i).Vy}\t" +
$"{setpoints.ElementAt(i).Vz}\t");
}
}
catch (Exception ex)
{
#if DEBUG
System.Diagnostics.Debug.WriteLine($"Logging exception: {ex.Message}");
#endif
}
finally
{
sw.Dispose();
fs.Dispose();
}
#if DEBUG
System.Diagnostics.Debug.WriteLine("Logging has been ended.");
#endif
}
// Static method
public void Start()
{
IsActive = true;
loggerTask = new Task(Logging);
loggerTask.Start();
}
public void Stop()
{
IsActive = false;
}
}
I have problem with intervals, because they are varying about 5-8 ms. My project requires maximum varying of 1-2 ms. Does anyone have idea how I can improve my approach.
Thank you for your responses.