| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- using System;
- using System.Collections.Generic;
- using System.Threading;
- namespace TeamAAS.Motion
- {
- /// <summary>
- /// 仿真运动卡:无硬件环境下的全功能实现(联调/演示/单元测试用)。
- /// 轴位置按指令速度渐变逼近目标(后台定时器推进),IO 点内存模拟。
- /// 品牌适配器(雷赛/固高/IMC60G)实现 IMotionCard 时可直接参照本类的状态机结构。
- /// </summary>
- public class SimulatedMotionCard : TeamAAS.Global.Devices.IMotionCard
- {
- private readonly MotionDeviceConfig _cfg;
- private readonly object _sync = new object();
- private readonly double[] _pos;
- private readonly double[] _target;
- private readonly double[] _vel;
- private readonly bool[] _moving;
- private readonly bool[] _homed;
- private readonly bool[] _enabled;
- public string Name => _cfg.Name;
- public int AxisCount => _cfg.AxisCount;
- public bool IsConnected { get; private set; }
- public SimulatedMotionCard(MotionDeviceConfig cfg)
- {
- _cfg = cfg ?? new MotionDeviceConfig();
- int n = Math.Max(1, _cfg.AxisCount);
- _pos = new double[n];
- _target = new double[n];
- _vel = new double[n];
- _moving = new bool[n];
- _homed = new bool[n];
- _enabled = new bool[n];
- // 后台轮询推进仿真轴运动(50ms 周期)
- var t = new System.Threading.Timer(Tick, null, 50, 50);
- }
- private void Tick(object state)
- {
- lock (_sync)
- {
- for (int i = 0; i < _pos.Length; i++)
- {
- if (!_moving[i]) continue;
- double step = _vel[i] * 0.05; // 50ms 周期
- double diff = _target[i] - _pos[i];
- if (Math.Abs(diff) <= step) { _pos[i] = _target[i]; _moving[i] = false; }
- else _pos[i] += Math.Sign(diff) * step;
- }
- }
- }
- public bool Open() { IsConnected = true; return true; }
- public void Close() { IsConnected = false; }
- public bool SetEnable(int axis, bool enable)
- {
- ApplyAxis(ref axis);
- lock (_sync) { _enabled[axis] = enable; }
- return true;
- }
- public bool Home(int axis, int mode = 0)
- {
- ApplyAxis(ref axis);
- lock (_sync) { _pos[axis] = 0; _target[axis] = 0; _moving[axis] = false; _homed[axis] = true; }
- return true;
- }
- public bool IsHomed(int axis) { lock (_sync) { return _homed[ClampAxis(axis)]; } }
- public bool MoveAbsolute(int axis, double position, double velocity)
- {
- ApplyAxis(ref axis);
- lock (_sync) { _target[axis] = position; _vel[axis] = Math.Abs(velocity) <= 0 ? 1 : Math.Abs(velocity); _moving[axis] = true; }
- return true;
- }
- public bool MoveRelative(int axis, double distance, double velocity)
- {
- lock (_sync) { return MoveAbsolute(axis, _pos[ClampAxis(axis)] + distance, velocity); }
- }
- public bool JogStart(int axis, int direction, double velocity)
- {
- ApplyAxis(ref axis);
- lock (_sync) { _target[axis] = direction >= 0 ? double.MaxValue : double.MinValue; _vel[axis] = Math.Abs(velocity) <= 0 ? 1 : Math.Abs(velocity); _moving[axis] = true; }
- return true;
- }
- public bool JogStop(int axis)
- {
- lock (_sync) { int i = ClampAxis(axis); _target[i] = _pos[i]; _moving[i] = false; }
- return true;
- }
- public bool Stop(int axis = -1)
- {
- lock (_sync)
- {
- for (int i = 0; i < _pos.Length; i++)
- {
- if (axis >= 0 && i != axis) continue;
- _target[i] = _pos[i]; _moving[i] = false;
- }
- }
- return true;
- }
- public TeamAAS.Global.Devices.AxisStatus GetAxisStatus(int axis)
- {
- int i = ClampAxis(axis);
- lock (_sync)
- {
- return new TeamAAS.Global.Devices.AxisStatus
- {
- Index = i,
- Name = $"轴{i}",
- Position = _pos[i],
- Velocity = _moving[i] ? _vel[i] : 0,
- IsMoving = _moving[i],
- IsHomed = _homed[i],
- IsEnabled = _enabled[i],
- };
- }
- }
- public List<TeamAAS.Global.Devices.AxisStatus> GetAllAxisStatus()
- {
- var list = new List<TeamAAS.Global.Devices.AxisStatus>();
- for (int i = 0; i < AxisCount; i++) list.Add(GetAxisStatus(i));
- return list;
- }
- private int ClampAxis(int axis) => Math.Max(0, Math.Min(axis < 0 ? 0 : axis, _pos.Length - 1));
- private void ApplyAxis(ref int axis)
- {
- if (axis < 0) axis = 0;
- if (axis >= _pos.Length) axis = _pos.Length - 1;
- }
- }
- /// <summary>仿真 IO 卡(16进/16出,内存模拟,批量接口齐全)。</summary>
- public class SimulatedIOCard : TeamAAS.Global.Devices.IIOCard
- {
- private readonly MotionDeviceConfig _cfg;
- private readonly bool[] _inputs;
- private readonly bool[] _outputs;
- public string Name => _cfg.Name;
- public int InputCount => _inputs.Length;
- public int OutputCount => _outputs.Length;
- public bool IsConnected { get; private set; }
- public SimulatedIOCard(MotionDeviceConfig cfg)
- {
- _cfg = cfg ?? new MotionDeviceConfig();
- _inputs = new bool[Math.Max(1, _cfg.InputCount)];
- _outputs = new bool[Math.Max(1, _cfg.OutputCount)];
- }
- public bool Open() { IsConnected = true; return true; }
- public void Close() { IsConnected = false; }
- public bool[] ReadAllInputs()
- {
- lock (_inputs) { return (bool[])_inputs.Clone(); }
- }
- public bool[] ReadAllOutputs()
- {
- lock (_outputs) { return (bool[])_outputs.Clone(); }
- }
- public bool WriteOutput(int index, bool value)
- {
- if (index < 0 || index >= _outputs.Length) return false;
- lock (_outputs) { _outputs[index] = value; }
- return true;
- }
- public bool WriteOutputs(bool[] values)
- {
- if (values == null) return false;
- lock (_outputs)
- {
- int n = Math.Min(values.Length, _outputs.Length);
- for (int i = 0; i < n; i++) _outputs[i] = values[i];
- }
- return true;
- }
- }
- }
|