MotionAxis.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. using Prism.Mvvm;
  2. using System;
  3. namespace SKMC.Api.Motion.Model
  4. {
  5. /// <summary>
  6. /// 电机模型
  7. /// </summary>
  8. public class MotionAxis : BindableBase
  9. {
  10. private long _id;
  11. public long Id
  12. {
  13. get { return _id; }
  14. set { _id = value; RaisePropertyChanged(); }
  15. }
  16. private string _type;
  17. /// <summary>
  18. /// 电机类型, Closed: 闭环, Open: 开环
  19. /// </summary>
  20. public string Type
  21. {
  22. get { return _type; }
  23. set { _type = value; }
  24. }
  25. private string _code;
  26. private short level;
  27. /// <summary>
  28. /// 安全等级, 0: 低压电机, 1: 高压电机
  29. /// </summary>
  30. public short Level
  31. {
  32. get { return level; }
  33. set { level = value; }
  34. }
  35. /// <summary>
  36. /// 电机码
  37. /// </summary>
  38. public string Code
  39. {
  40. get { return _code; }
  41. set { _code = value; RaisePropertyChanged(); }
  42. }
  43. private string catalog;
  44. /// <summary>
  45. /// 所属(模块)分类
  46. /// </summary>
  47. public string Catalog
  48. {
  49. get { return catalog; }
  50. set { catalog = value; RaisePropertyChanged(); }
  51. }
  52. private short _axisNo;
  53. /// <summary>
  54. /// 电机序号
  55. /// </summary>
  56. public short AxisNo
  57. {
  58. get { return _axisNo; }
  59. set { _axisNo = value; RaisePropertyChanged(); }
  60. }
  61. private char _axisDir;
  62. public char AxisDir
  63. {
  64. get { return _axisDir; }
  65. set { _axisDir = value; RaisePropertyChanged(); }
  66. }
  67. /// <summary>
  68. /// 默认的安全检查函数, 用于电机调试时
  69. /// </summary>
  70. public Func<bool> SafeChecker { get; set; }
  71. private MotionAxisStatus _axisSts;
  72. /// <summary>
  73. /// 电机状态
  74. /// </summary>
  75. public MotionAxisStatus AxisSts
  76. {
  77. get { return _axisSts; }
  78. set { _axisSts = value; RaisePropertyChanged(); }
  79. }
  80. /// <summary>
  81. /// 到位时允许的偏差 (mm)
  82. /// </summary>
  83. public double InRange { get; set; }
  84. /// <summary>
  85. /// 是否已停止
  86. /// </summary>
  87. public bool IsStopped => _axisSts.IsBusy == 0 && _axisSts.IsDone == 1;
  88. /// <summary>
  89. /// 是否上使能
  90. /// </summary>
  91. public bool IsEnabled => _axisSts.IsEnable == 1;
  92. /// <summary>
  93. /// <para>如果该轴出现异常, 是否会中断其他电机与IO控制</para>
  94. /// <para>如果需要对该轴出现异常后进行恢复处理, 为不影响到其他电机与IO控制, 这里需要设置为false</para>
  95. /// </summary>
  96. public bool CanInterruptAll { get; set; } = true;
  97. /// <summary>
  98. /// 是否已回零
  99. /// </summary>
  100. public bool IsHomed
  101. {
  102. get => _axisSts.IsHomed == 1;
  103. set => _axisSts.IsHomed = value ? (byte)1 : (byte)0;
  104. }
  105. private string _name;
  106. /// <summary>
  107. /// 名称/描述
  108. /// </summary>
  109. public string Name
  110. {
  111. get { return _name; }
  112. set { _name = value; RaisePropertyChanged(); }
  113. }
  114. private string _ptag;
  115. /// <summary>
  116. /// 正方向运动标签, 默认→
  117. /// </summary>
  118. public string PTag
  119. {
  120. get { return _ptag; }
  121. set { _ptag = value; }
  122. }
  123. private string _ntag;
  124. /// <summary>
  125. /// 负方向运动标签, 默认←
  126. /// </summary>
  127. public string NTag
  128. {
  129. get { return _ntag; }
  130. set { _ntag = value; }
  131. }
  132. private short _homeMod;
  133. /// <summary>
  134. /// 驱动器回零模式
  135. /// </summary>
  136. public short HomeMod
  137. {
  138. get { return _homeMod; }
  139. set { _homeMod = value; RaisePropertyChanged(); }
  140. }
  141. private short _homeDir;
  142. /// <summary>
  143. /// 回零方向
  144. /// </summary>
  145. public short HomeDir
  146. {
  147. get { return _homeDir; }
  148. set { _homeDir = value; RaisePropertyChanged(); }
  149. }
  150. private double _lowVel;
  151. /// <summary>
  152. /// 回零低速
  153. /// </summary>
  154. public double LowVel
  155. {
  156. get { return _lowVel; }
  157. set { _lowVel = value; RaisePropertyChanged(); }
  158. }
  159. private double _highVel;
  160. /// <summary>
  161. /// 回零高速
  162. /// </summary>
  163. public double HighVel
  164. {
  165. get { return _highVel; }
  166. set { _highVel = value; RaisePropertyChanged(); }
  167. }
  168. public string SerialNo { get => $"[{AxisNo}]{AxisDir}: {Code}"; }
  169. public string SerialName { get => $"[{Code}]: {Name}"; }
  170. private int _gearScale;
  171. /// <summary>
  172. /// 电子齿轮比
  173. /// </summary>
  174. public int GearScale
  175. {
  176. get { return _gearScale; }
  177. set { _gearScale = value; }
  178. }
  179. private double _distanceR;
  180. /// <summary>
  181. /// 电机每旋转一圈机构的移动距离, 可以是螺距导程, 也可以是传动轮周长
  182. /// </summary>
  183. public double DistanceR
  184. {
  185. get { return _distanceR; }
  186. set { _distanceR = value; }
  187. }
  188. private short _unitType;
  189. // 单位类型, 0表示电机步距, 1表示实际距离
  190. public short UnitType
  191. {
  192. get { return _unitType; }
  193. set { _unitType = value; }
  194. }
  195. private string _unitName;
  196. // 单位名称用于显示, 例如mm, °等
  197. public string UnitName
  198. {
  199. get { return _unitName; }
  200. set { _unitName = value; }
  201. }
  202. private string _moveType;
  203. // 移动类型, L直线, R旋转
  204. public string MoveType
  205. {
  206. get { return _moveType; }
  207. set { _moveType = value; }
  208. }
  209. /// <summary>
  210. /// 距离(mm)对应的电机运动单位
  211. /// </summary>
  212. public double DistanceUnit
  213. {
  214. get => _gearScale / _distanceR;
  215. }
  216. /// <summary>
  217. /// 当前ENC值对应的实际距离mm
  218. /// </summary>
  219. public double Distance
  220. {
  221. get => _axisSts.ENC / DistanceUnit;
  222. }
  223. /// <summary>
  224. /// 离上一次记录的实际距离 mm
  225. /// </summary>
  226. public double WatchDistance => _axisSts.WatchPos / DistanceUnit;
  227. private double _prfUnit;
  228. /// <summary>
  229. /// 运动目标值, 实际单位mm或者角度等
  230. /// </summary>
  231. public double PrfUnit
  232. {
  233. get { return _prfUnit; }
  234. set
  235. {
  236. _prfUnit = value / DistanceUnit;
  237. AxisSts.PRF = value;
  238. RaisePropertyChanged();
  239. }
  240. }
  241. private double _encUnit;
  242. /// <summary>
  243. /// 运动反馈值, 实际单位mm或者角度等
  244. /// </summary>
  245. public double EncUnit
  246. {
  247. get { return _encUnit; }
  248. set
  249. {
  250. _encUnit = value / DistanceUnit;
  251. AxisSts.ENC = value;
  252. if (PercentOn) Percent = (_encUnit - NegativeUnit) / (PositiveUnit - NegativeUnit);
  253. RaisePropertyChanged();
  254. }
  255. }
  256. /// <summary>
  257. /// 是否使用位置百分比
  258. /// </summary>
  259. public bool PercentOn { get; set; }
  260. /// <summary>
  261. /// 负限位位置(mm)
  262. /// </summary>
  263. public double NegativeUnit { get; set; }
  264. /// <summary>
  265. /// 正限位位置(mm)
  266. /// </summary>
  267. public double PositiveUnit { get; set; }
  268. private double percent;
  269. /// <summary>
  270. /// 位置百分比, 负限位为0%, 正限位为100%
  271. /// </summary>
  272. public double Percent
  273. {
  274. get { return percent; }
  275. set { percent = value; RaisePropertyChanged(); }
  276. }
  277. /// <summary>
  278. /// 电机停止(中断)
  279. /// </summary>
  280. public bool IsInterrupt { get; set; }
  281. /// <summary>
  282. /// 被占用的handler
  283. /// </summary>
  284. public int? LockHandler { get; set; }
  285. /// <summary>
  286. /// 当前位置是否在偏移量之内
  287. /// </summary>
  288. /// <param name="targetVal"></param>
  289. /// <param name="offset"></param>
  290. /// <returns></returns>
  291. public bool IsEncInRange(double targetVal)
  292. {
  293. if (_encUnit == targetVal) return true;
  294. else if (_encUnit > targetVal) return _encUnit - targetVal <= InRange;
  295. else return targetVal - _encUnit <= InRange;
  296. }
  297. /// <summary>
  298. /// 当前位置是否在偏移量之内
  299. /// </summary>
  300. /// <param name="targetVal"></param>
  301. /// <param name="offset"></param>
  302. /// <returns></returns>
  303. public bool IsEncInRange(double targetVal, double offset)
  304. {
  305. if (_encUnit == targetVal) return true;
  306. else if (_encUnit > targetVal) return _encUnit - targetVal <= offset;
  307. else return targetVal - _encUnit <= offset;
  308. }
  309. }
  310. }