ln.ethercat/ln.ethercat/controller/ControllerRemote.cs

116 lines
3.3 KiB
C#

using System;
using System.Threading;
using ln.ethercat.controller.drives;
using ln.ethercat.controller.remote;
using ln.logging;
namespace ln.ethercat.controller
{
public enum CRActions {
NONE, // No Action
ENABLE, // Enable system (turn on)
DISABLE, // Disable system (turn off)
CLEARFAULT, // Clear fault state
}
public abstract class ControllerRemote : IDisposable
{
protected Controller Controller;
public double CycleIntervall { get; set; }
public double CycleFrequency {
get => 1.0 / CycleIntervall;
set => CycleIntervall = 1.0 / value;
}
public long CycleCounter { get; private set; }
public bool IsRunning => threadCycle?.IsAlive ?? false;
bool stopCycleThread;
Thread threadCycle;
public ControllerRemote(Controller controller)
{
Controller = controller;
Controller?.Add(this);
}
public abstract double[] Targets { get; set; }
public abstract FeederOperation FeederOperation { get; }
public void Start()
{
lock (this)
{
if (threadCycle?.IsAlive ?? false)
Stop();
threadCycle = new Thread(CycleThread);
threadCycle.Start();
}
}
public void Stop()
{
lock (this)
{
if (threadCycle?.IsAlive ?? false)
{
stopCycleThread = true;
threadCycle.Join(250);
if (threadCycle.IsAlive)
threadCycle.Abort();
threadCycle = null;
}
}
}
public void SetTargetValue(int drive, double targetValue) => Controller.RemoteUpdateTarget( drive, targetValue );
public void Action(CRActions action) => Controller.RemoteAction(action);
protected abstract void Initialize();
protected abstract void Cycle();
protected abstract void Shutdown();
public abstract bool IsSafeToEnable();
private void CycleThread()
{
CycleCounter = 0;
Initialize();
DateTime nextCycleRun = DateTime.Now;
while (!stopCycleThread)
{
DateTime currentTime = DateTime.Now;
nextCycleRun += TimeSpan.FromSeconds(CycleIntervall);
if (currentTime > nextCycleRun)
{
Logging.Log(LogLevel.WARNING, "ControllerRemote: missed controller cycle");
while (currentTime > nextCycleRun)
nextCycleRun += TimeSpan.FromSeconds(CycleIntervall);
}
TimeSpan timeToNextCycle = nextCycleRun - currentTime;
try
{
Thread.Sleep(timeToNextCycle);
CycleCounter++;
Cycle();
} catch (Exception e)
{
Logging.Log(e);
}
}
Shutdown();
}
public void Dispose()
{
Controller?.Remove(this);
}
}
}