周立功开发过程1

This commit is contained in:
2026-02-02 21:22:01 +08:00
parent 4d16b474c6
commit 2e8ad1cffa
42 changed files with 11571 additions and 122 deletions

View File

@@ -0,0 +1,320 @@
using CapMachine.Model.CANLIN;
using CapMachine.Wpf.CanDrive;
using CapMachine.Wpf.CanDrive.ZlgCan;
using ImTools;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace CapMachine.Wpf.Services
{
/// <summary>
/// ZLG CAN/CANFD 驱动服务(共享设备句柄)。
/// </summary>
public sealed class ZlgCanDriveService : BindableBase
{
private readonly ILogService _log;
/// <summary>
/// 共享的 ZLG 驱动实例CAN/CANFD/LIN
/// </summary>
public ZlgCanFd200uDriver Driver { get; }
/// <summary>
/// 当前选中的配置程序(沿用原有 FreeSql 模型)。
/// </summary>
public CanLinConfigPro? SelectedCanLinConfigPro { get; set; }
/// <summary>
/// Dbc 消息集合(用于 UI 绑定)。
/// </summary>
public ObservableCollection<CanDbcModel> ListCanDbcModel { get; private set; } = new ObservableCollection<CanDbcModel>();
private bool _dbcParserState;
/// <summary>
/// DBC 解析状态。
/// </summary>
public bool DbcParserState
{
get { return _dbcParserState; }
private set { _dbcParserState = value; RaisePropertyChanged(); }
}
private bool _openState;
/// <summary>
/// 设备打开状态。
/// </summary>
public bool OpenState
{
get { return _openState; }
private set { _openState = value; RaisePropertyChanged(); }
}
private ZlgCanMode _mode;
/// <summary>
/// CAN 模式单选CAN 或 CANFD
/// </summary>
public ZlgCanMode Mode
{
get { return _mode; }
set { _mode = value; RaisePropertyChanged(); }
}
/// <summary>
/// 发送使能(与 UI 的调度表使能语义对齐)。
/// </summary>
public bool SchEnable
{
get { return Driver.SchEnable; }
set { Driver.SchEnable = value; RaisePropertyChanged(); }
}
/// <summary>
/// 是否启用事件驱动发送。
/// </summary>
public bool IsCycleSend
{
get { return Driver.IsCycleSend; }
set { Driver.IsCycleSend = value; RaisePropertyChanged(); }
}
/// <summary>
/// 是否正在循环接收(对齐 ToomossIsCycleRevice
/// </summary>
public bool IsCycleRevice
{
get { return Driver.IsReceiving; }
}
/// <summary>
/// 最近是否发送成功(用于 UI 指示)。
/// </summary>
public bool IsSendOk
{
get { return Driver.IsSendOk; }
}
/// <summary>
/// 最近是否接收成功(用于 UI 指示)。
/// </summary>
public bool IsReviceOk
{
get { return Driver.IsReviceOk; }
}
/// <summary>
/// 要发送的 CAN 指令数据。
/// </summary>
public List<CanCmdData> CmdData { get; } = new List<CanCmdData>();
private CanCmdData? SpeedCanCmdData { get; set; }
private uint _deviceIndex = 0;
private ZlgCanFdChannelOptions _channel0 = new ZlgCanFdChannelOptions();
/// <summary>
/// 构造。
/// </summary>
/// <param name="logService">日志服务。</param>
public ZlgCanDriveService(ILogService logService)
{
_log = logService;
Driver = new ZlgCanFd200uDriver(logService);
Driver.PropertyChanged += (_, __) =>
{
OpenState = Driver.OpenState;
RaisePropertyChanged(nameof(IsCycleRevice));
RaisePropertyChanged(nameof(IsSendOk));
RaisePropertyChanged(nameof(IsReviceOk));
};
OpenState = Driver.OpenState;
Mode = ZlgCanMode.Can;
}
/// <summary>
/// 初始化 CAN 配置信息,并将配置中的名称映射到 DBC 信号集合(用于 UI 显示)。
/// </summary>
/// <param name="selectedCanLinConfigPro">选中的配置。</param>
public void InitCanConfig(CanLinConfigPro selectedCanLinConfigPro)
{
SelectedCanLinConfigPro = selectedCanLinConfigPro;
if (SelectedCanLinConfigPro?.CanLinConfigContents == null) return;
foreach (var item in SelectedCanLinConfigPro.CanLinConfigContents)
{
var find = ListCanDbcModel.FindFirst(a => a.SignalName == item.SignalName);
if (find != null)
{
find.Name = item.Name;
}
}
}
/// <summary>
/// 更新配置(从 DTO/DB 同步到驱动)。
/// </summary>
/// <param name="deviceIndex">设备索引。</param>
/// <param name="arbBaudRate">仲裁波特率bps。</param>
/// <param name="dataBaudRate">数据波特率bps。</param>
/// <param name="resEnable">终端电阻使能。</param>
/// <param name="mergeReceive">是否合并接收。</param>
/// <param name="mergeReceiveBufferFrames">合并接收缓冲帧数。</param>
public void UpdateConfig(uint deviceIndex, uint arbBaudRate, uint dataBaudRate, bool resEnable, bool mergeReceive = false, int mergeReceiveBufferFrames = 100)
{
_deviceIndex = deviceIndex;
_channel0.ArbitrationBaudRate = arbBaudRate;
_channel0.DataBaudRate = dataBaudRate;
_channel0.EnableInternalResistance = resEnable;
_channel0.EnableMergeReceive = mergeReceive;
_channel0.MergeReceiveBufferFrames = mergeReceiveBufferFrames;
}
/// <summary>
/// 打开 CAN/CANFD按 Mode
/// </summary>
public void StartCanDrive()
{
if (OpenState)
{
return;
}
Driver.OpenAndInitCan(_deviceIndex, _channel0);
Driver.StartReceiveLoop(_channel0.EnableMergeReceive, _channel0.MergeReceiveBufferFrames);
OpenState = Driver.OpenState;
}
/// <summary>
/// 使能/停止循环接收。
/// </summary>
/// <param name="enable">true=启动接收线程false=停止接收线程。</param>
public void SetReceiveEnabled(bool enable)
{
if (!OpenState)
{
throw new InvalidOperationException("设备未连接,无法切换循环接收。");
}
if (enable)
{
if (!Driver.IsReceiving)
{
Driver.StartReceiveLoop(_channel0.EnableMergeReceive, _channel0.MergeReceiveBufferFrames);
}
}
else
{
if (Driver.IsReceiving)
{
Driver.StopReceiveLoop();
}
}
RaisePropertyChanged(nameof(IsCycleRevice));
}
/// <summary>
/// 关闭设备(会同时关闭共享的 LIN 通道)。
/// </summary>
public void CloseDevice()
{
try
{
Driver.Close();
}
finally
{
OpenState = Driver.OpenState;
DbcParserState = false;
}
}
/// <summary>
/// 加载 DBC。
/// </summary>
/// <param name="path">DBC 路径。</param>
public ObservableCollection<CanDbcModel> StartDbc(string path)
{
if (!OpenState)
{
throw new InvalidOperationException("请先打开设备后再加载 DBC。");
}
ListCanDbcModel = Driver.StartDbc(path);
DbcParserState = ListCanDbcModel != null && ListCanDbcModel.Count > 0;
return ListCanDbcModel;
}
/// <summary>
/// 加载要发送的数据(订阅数据变化事件)。
/// </summary>
/// <param name="cmdData">指令数据集合。</param>
public void LoadCmdDataToDrive(List<CanCmdData> cmdData)
{
var list = cmdData ?? new List<CanCmdData>();
CmdData.Clear();
CmdData.AddRange(list);
foreach (var item in CmdData)
{
if (string.Equals(item.ConfigName, "转速", StringComparison.Ordinal))
{
SpeedCanCmdData = item;
}
}
Driver.LoadCmdDataToDrive(CmdData, channelIndex: 0, frameType: Mode == ZlgCanMode.Can ? (byte)ZDBC.FT_CAN : (byte)ZDBC.FT_CANFD);
}
/// <summary>
/// 手动发送(目前对齐原服务:仅发送转速)。
/// </summary>
/// <param name="speedData">转速。</param>
public void SendMsgToCanDrive(double speedData)
{
if (!OpenState)
{
return;
}
if (SpeedCanCmdData != null)
{
SpeedCanCmdData.SignalCmdValue = speedData;
}
else
{
_log.Warn("未配置转速指令项ConfigName=转速),忽略手动发送。");
}
// 若未启用事件驱动发送,则这里主动发送一次(与旧行为兼容)
if (!IsCycleSend || !SchEnable)
{
var firstMsg = CmdData.FirstOrDefault()?.MsgName;
if (!string.IsNullOrWhiteSpace(firstMsg))
{
Driver.SendOneMsgByCmdData(firstMsg, 0, Mode == ZlgCanMode.Can ? (byte)ZDBC.FT_CAN : (byte)ZDBC.FT_CANFD);
}
}
}
}
/// <summary>
/// ZLG CAN 工作模式。
/// </summary>
public enum ZlgCanMode
{
/// <summary>
/// CAN 经典帧。
/// </summary>
Can = 0,
/// <summary>
/// CAN FD。
/// </summary>
CanFd = 1
}
}