using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Beckhoff.IOAxis;
using MECF.Framework.Common.CommonData.PUF;
using MECF.Framework.Common.TwinCat;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Mono.Security.X509.X520;
namespace PunkHPX8_RT.Devices.AXIS
{
public class BeckhoffCommonAxis
{
#region 常量
private const string STATUS_WORD = "StatusWord";
private const string DIGITAL_INPUTS = "DigitalInputs";
private const string CONTROL_WORD = "ControlWord";
private const string MODE_OF_OPERATION = "ModeOfOperation";
protected const string PROFILE_VELOCITY = "ProfileVelocity";
protected const string PROFILE_ACCEL = "ProfileAccel";
protected const string PROFILE_DECEL = "ProfileDecel";
private const string REFERENCE_POSITION = "ReferencePosition";
private const string TARGET_POSITION = "TargetPosition";
private const string ACTUAL_VELOCITY = "Velocity";
private const string ACTUAL_TORQUE = "ActualTorque";
private const string POSITION_ERROR = "PositionError";
private const string MOTOR_POSITION = "MotorPosition";
private const string HOME_OFFSET = "HomeOffset";
private const string HOMING_METHOD = "HomingMethod";
protected const string HOMING_VELOCITY = "HomingVelocity";
protected const string HOMING_VELOCITY_SLOW = "HomingVelocitySlow";
protected const string HOMING_ACCEL = "HomingAccel";
private const string NEGATIVE_TORQUE_LIMIT = "NegativeTorqueLimit";
private const string POSITIVE_TORQUE_LIMIT = "PositiveTorqueLimit";
private const string MANUF_STATUS = "ManufStatus";
private const string SOFTWARE_LIMIT_MINUS = "SoftwareLimitMinus";
private const string SOFTWARE_LIMIT_PLUS = "SoftwareLimitPlus";
#endregion
#region 内部变量
///
/// 模块名称
///
private string _module;
///
/// 名称
///
private string _name;
///
/// 电机对象
///
private JetAxisBase _axis;
///
/// coe输出变量集合
///
private List _coeOutputs = new List();
///
/// coe连接状态
///
private bool _coeConnected = false;
///
/// beckhoff axis配置
///
private BeckhoffAxis _beckhoffAxis;
#endregion
///
/// 初始化
///
///
///
public BeckhoffCommonAxis(string module, string name,JetAxisBase axis)
{
_module = module;
_name = name;
_axis = axis;
}
///
/// 初始化COE输出变量集合
///
public void InitializeCoeOutputs(BeckhoffAxis beckhoffAxis)
{
_beckhoffAxis= beckhoffAxis;
if (beckhoffAxis != null)
{
foreach (BeckhoffAxisOutput item in beckhoffAxis.Outputs)
{
if (!_coeOutputs.Contains(item.Type) && item.Address.StartsWith("0x"))
{
_coeOutputs.Add(item.Type);
}
}
}
}
///
/// 首次写入COE
///
public void FirstStartUpWriteCOE(string variable)
{
if (_coeOutputs.Contains(variable))
{
if (!_coeConnected)
{
_coeConnected = true;
StartUpWriteCoeThread();
}
}
}
///
/// 启动写COE变量数值线程
///
public void StartUpWriteCoeThread()
{
bool isSimulator = SC.GetValue("System.IsSimulatorMode");
if (!isSimulator)
{
Thread thread = new Thread(new ThreadStart(StartUpWriteCoeVariable));
thread.IsBackground = true;
thread.Start();
}
}
///
/// 启动写COE变量数值
///
public void StartUpWriteCoeVariable()
{
LOG.WriteLog(eEvent.INFO_AXIS, _module, "start write coe thread");
byte homingMethod = _beckhoffAxis.HomingMethod;
WriteCoeVariable(HOMING_METHOD, homingMethod);
//homing accel
WriteCoeVariable(HOMING_ACCEL, _axis.CalculateDivideAccelerationRatio(_beckhoffAxis.HomingAccelDecel));
//homing speed home switch
WriteCoeVariable(HOMING_VELOCITY, _axis.CalculateMultiplySpeedRatio(_beckhoffAxis.HomingSpeedHomeSwitch));
WriteCoeVariable(HOMING_VELOCITY_SLOW, _axis.CalculateMultiplySpeedRatio(_beckhoffAxis.HomingSpeedEncoderIndex));
WriteCoeVariable(HOME_OFFSET, _beckhoffAxis.HomingOffset);
int negativeTorqueLimit = _beckhoffAxis.NegativeTorqueLimit;
if (negativeTorqueLimit != 0)
{
WriteCoeVariable(NEGATIVE_TORQUE_LIMIT, negativeTorqueLimit);
}
int positiveTorqueLimit = _beckhoffAxis.PositiveTorqueLimit;
if (positiveTorqueLimit != 0)
{
WriteCoeVariable(POSITIVE_TORQUE_LIMIT, positiveTorqueLimit);
}
int softwareForwardLimit = _beckhoffAxis.ForwardSoftwareLimit;
if (softwareForwardLimit != 0)
{
WriteCoeVariable(SOFTWARE_LIMIT_PLUS, softwareForwardLimit);
}
int softReverseLimit = _beckhoffAxis.ReverseSoftwareLimit;
if (softReverseLimit != 0)
{
WriteCoeVariable(SOFTWARE_LIMIT_MINUS, softReverseLimit);
}
//WriteCoeVariable(PROFILE_VELOCITY,CalculateMultiplySpeedRatio(_beckhoffAxis.Speed));
//WriteCoeVariable(PROFILE_ACCEL, CalculateDivideAccelerationRatio(_beckhoffAxis.Acceleration));
//WriteCoeVariable(PROFILE_DECEL,CalculateDivideAccelerationRatio(_beckhoffAxis.Deceleration));
}
///
/// 写COE变量数值
///
///
///
private void WriteCoeVariable(string variableName, object value)
{
string str = $"{_module}.{_name}";
if (_coeOutputs.Contains(variableName))
{
bool result = TwincatCoeManager.Instance.WriteVariableValue(str, variableName, value);
if (result)
{
LOG.WriteLog(eEvent.INFO_AXIS, str, $"coe variable {variableName} value {value} success");
}
}
}
///
/// 订阅变量
///
public void SubscriptionVariable()
{
_axis.AxisSubscribeUpdateVariable(STATUS_WORD);
_axis.AxisSubscribeUpdateVariable(DIGITAL_INPUTS);
_axis.AxisSubscribeUpdateVariable(CONTROL_WORD);
_axis.AxisSubscribeUpdateVariable(MODE_OF_OPERATION);
_axis.AxisSubscribeUpdateVariable(PROFILE_VELOCITY);
_axis.AxisSubscribeUpdateVariable(PROFILE_ACCEL);
_axis.AxisSubscribeUpdateVariable(PROFILE_DECEL);
_axis.AxisSubscribeUpdateVariable(REFERENCE_POSITION);
_axis.AxisSubscribeUpdateVariable(TARGET_POSITION);
_axis.AxisSubscribeUpdateVariable(MOTOR_POSITION);
_axis.AxisSubscribeUpdateVariable(POSITION_ERROR);
_axis.AxisSubscribeUpdateVariable(ACTUAL_TORQUE);
_axis.AxisSubscribeUpdateVariable(ACTUAL_VELOCITY);
_axis.AxisSubscribeUpdateVariable(HOME_OFFSET);
_axis.AxisSubscribeUpdateVariable(HOMING_METHOD);
_axis.AxisSubscribeUpdateVariable(HOMING_VELOCITY);
_axis.AxisSubscribeUpdateVariable(HOMING_VELOCITY_SLOW);
_axis.AxisSubscribeUpdateVariable(POSITIVE_TORQUE_LIMIT);
_axis.AxisSubscribeUpdateVariable(NEGATIVE_TORQUE_LIMIT);
_axis.AxisSubscribeUpdateVariable(HOMING_ACCEL);
_axis.AxisSubscribeUpdateVariable(MANUF_STATUS);
}
///
/// 写入控制字
///
///
public bool WriteControlWord(ushort controlWord)
{
return BeckhoffAxisManager.Instance.WriteVariableValue($"{_module}.{_name}.{CONTROL_WORD}", controlWord);
}
///
/// 写入ModeOfOperation
///
///
///
public bool WriteModeOfMode(AxisModeOfOperation modeOfOperation)
{
return BeckhoffAxisManager.Instance.WriteVariableValue($"{_module}.{_name}.{MODE_OF_OPERATION}", (byte)modeOfOperation);
}
///
/// 写变量数值
///
///
///
///
public bool WriteVariable(string variableName, object value)
{
return BeckhoffAxisManager.Instance.WriteVariableValue($"{_module}.{_name}.{variableName}", value);
}
}
}