Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中以10-15毫秒的间隔记录来自结构的数据#_C#_Logging_Timer_Intervals - Fatal编程技术网

C# 在C中以10-15毫秒的间隔记录来自结构的数据#

C# 在C中以10-15毫秒的间隔记录来自结构的数据#,c#,logging,timer,intervals,C#,Logging,Timer,Intervals,我必须准备Logger类,该类将以10-15毫秒的间隔保存3个结构的数据。我解决此问题的方法如下: public class Logger { // Variables private Task loggerTask; public bool IsActive { get; set; } // Constructor public Logger() { } private void Logging() { #i

我必须准备Logger类,该类将以10-15毫秒的间隔保存3个结构的数据。我解决此问题的方法如下:

    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;
    }
}
公共类记录器
{
//变数
私有任务日志任务;
公共bool IsActive{get;set;}
//建造师
公共记录器()
{
}
私有无效日志记录()
{
#如果调试
System.Diagnostics.Debug.WriteLine(“日志记录已启动”);
#恩迪夫
FileStream fs=newfilestream($”/log{DateTime.Now.ToString(“dd.MM HH.MM.ss”)}.txt),FileMode.Create,FileAccess.Write);
StreamWriter sw=新StreamWriter(fs,Encoding.Default);
尝试
{
队列时间=新队列();
队列态度=新队列();
队列位置=新队列();
队列设置点=新队列();
//日志数据
DateTime start=DateTime.Now;
DateTime last=开始;
现在是约会时间;
while(IsActive)
{
现在=日期时间。现在;
如果((现在-最后).total毫秒<16)
继续;
最后=现在;
times.Enqueue((now-start).total毫秒);
态度。排队(地面军事系统实例。无人机。态度);
positions.Enqueue(GCS.Instance.Drone.localpositioned);
设置点。排队(GCS.Instance.Offboard.SetPoint);
}
//保存数据
for(int i=0;i
我对时间间隔有问题,因为它们的变化范围约为5-8毫秒。我的项目要求最大变化范围为1-2毫秒。有人知道我如何改进我的方法吗


感谢您的回复。

最大的问题可能是使用
日期时间。现在
的分辨率很低,不适合此类任务

一个更合适的简单替代方案是

var延迟=16;
var stopwatch=stopwatch.StartNew();
长电流=0;
很久以前;
var next=秒表.ElapsedMilliseconds+延迟;
对于(int i=0;i<100;i++)
{
while(下一步>秒表。延时百万秒)
{
//旋转
}
next=秒表.ElapsedMilliseconds+延迟;
先前=当前;
当前=秒表。延时毫秒;
var delta=当前-先前;
控制台写入线(“增量:+增量”);
}

如评论中所述,这并没有提供任何有力的保证,只是尽了最大努力。还有更好的方法可以做到这一点,而不浪费整个线程什么也不做,例如使用。但是,只要CPU上的负载很轻,它就足以用于测试/调试目的。

因为运行此代码的操作系统很可能不是实时操作系统,所以它无法提供如此严格的定时保证。在任何时候,操作系统都可能决定您的进程\线程有足够的CPU时间,并切换到另一个进程\线程,然后在未知的时间后返回到您的进程。即使5-8毫秒也不能保证—10毫秒的延迟并不罕见,整秒也不未知。在像Windows这样的非实时操作系统上,你根本无法达到这样的精度。好吧,我明白。但还有一个问题。如何检查我的操作系统能保证哪种精度?非实时操作系统不能保证任何精度。对于实时操作系统,请查看文档。例如,RTLinux。一个简单的解决方案是将应用程序的优先级更改为更高的优先级,以便获得更均匀的数据。应用程序以正常优先级运行,因此操作系统任务的优先级高于应用程序,并且响应不均匀。
        var delay = 16;
        var stopwatch = Stopwatch.StartNew();
        long current = 0;
        long previous;
        var next = stopwatch.ElapsedMilliseconds + delay;
        for (int i = 0; i < 100; i++)
        {

            while (next > stopwatch.ElapsedMilliseconds)
            {
                // Spin
            }

            next = stopwatch.ElapsedMilliseconds + delay;

            previous = current;
            current = stopwatch.ElapsedMilliseconds;
            var delta = current - previous;
            Console.WriteLine("Delta: " + delta);
        }