2 Star 1 Fork 0

MAMAMA / CrankshaftAnalysisSystem

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
MeasureSystem.cs 19.07 KB
一键复制 编辑 原始数据 按行查看 历史
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CrankShaftAnalysisSystem.Controller;
using CrankShaftAnalysisSystem.Devices;
using System.Text.Json;
using System.IO;
using CrankShaftResultHandler;
namespace CrankShaftAnalysisSystem
{
public class MeasureSystem
{
private static readonly MeasureSystem instance = new MeasureSystem();
/// <summary>
/// 显式的静态构造函数用来告诉C#编译器在其内容实例化之前不要标记其类型
/// 静态构造函数是C#的一个新特性,其实好像很少用到。
/// 不过当我们想初始化一些静态变量的时候就需要用到它了。 这个构造函数是属于类的,
/// 而不是属于哪里实例的,就是说这个构造函数只会被执行一次。
/// 也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用
/// </summary>
static MeasureSystem() { }
[Description("东方量仪设备")]
public DistanceEastenGauge Easten { get; set; }
[Description("海德汉直线光栅尺")]
public LinearLC485 LC485 { get; set; }
[Description("海德汉笔式传感器")]
public DistanceMT2571 MT2571 { get; set; }
[Description("海德汉角度编码器")]
public EncoderERM2400 ERM2400 { get; set; }
[Description("PLC设备")]
public PLCMaster PLC { get; set; }
[Description("测量进度")]
public double Process { get; set; }
[Description("测量启动时间")]
public DateTime StartTime { get; private set; }
[Description("测量耗时")]
public TimeSpan MeasureDuration { get; private set; }
[Description("当前绑定的数据")]
public DataStorage DataBase { get; private set; }
[Description("测量时的相对角度")]
public double RelativeDegrees { get; private set; }
private MeasureSystem()
{
Easten = DistanceEastenGauge.Instance;
LC485 = LinearLC485.Instance;
MT2571 = DistanceMT2571.Instance;
ERM2400 = EncoderERM2400.Instance;
PLC = PLCMaster.Instance;
StartTime = DateTime.Now;
}
public enum State
{
IDLE,
BUSY,
FINISHED
}
public State OneStepMeasureState { get; private set; } = State.IDLE;
public State MeasureState { get; private set; } = State.IDLE;
public bool IsManualStop { get; private set; } = false;
public static PointMeasureConfig pointMeasureConfig { get; private set; }
public static PointMeasureConfig.Configs MeasureSetting { get; set; }
[Description("单个高度的测量总角度")]
public double MeasuringDegrees { get; set; } = 360.0;
[Description("测量的时候的转速")]
public int MeasuringRPM { get; set; } = 600;
public const int PreMeasuringRPM = 600; // 跑合速度
public int TotalMeasurePoints { get; private set; }
public int CurrentMeasurePointIndex { get; private set; } = 0;
public string CurrentTaskName { get; private set; } = "等待测量开始";
public void SafetyFinishMeaure()
{
MeasureState = State.FINISHED;
}
public void StopMeasuring()
{
IsManualStop = true;
}
public void LoadPointConfig(string path)
{
using (var file = new StreamReader(path))
{
var cfg = file.ReadToEnd();
pointMeasureConfig = JsonSerializer.Deserialize<PointMeasureConfig>(cfg);
MeasureSetting = typeof(PointMeasureConfig).GetProperty(pointMeasureConfig.CurrentType).GetValue(pointMeasureConfig) as PointMeasureConfig.Configs;
MeasureSetting.Tolerance.CopyTo(ref ResultHandler.Tolerance);
}
}
public void Begin()
{
if (Properties.Settings.Default.OfflineMode)
{
Console.WriteLine("System Run As Offline Mode");
return;
}
Easten.LoadSetting();
Easten.Device.begin();
LC485.Begin();
MT2571.Begin();
ERM2400.Device.Begin();
PLC.Device.begin();
}
/// <summary>
/// 旋转使得转台刚刚越过零点
/// </summary>
/// <returns></returns>
private Task MoveThroughZero()
{
return Task.Run(() =>
{
PLC.SetSpeed(1, -100);
while (true)
{
var rad = ERM2400.Device.ReadAngleRadians(out _);
if (rad > 0)
{
Console.WriteLine("Move Through Zero Finish");
break;
}
if (SafeController.ManualStop)
{
Console.WriteLine("[Safe Controller]: StopAll.");
break;
}
Thread.Sleep(100);
}
PLC.SetSpeed(1, 0);
});
}
public Task VacuumOn()
{
return Task.Run(() =>
{
Console.WriteLine("Vacuum On.");
LogicalController.VacuumOn();
});
}
public Task VacuumOff()
{
return Task.Run(() =>
{
Console.WriteLine("Vacuum Off.");
LogicalController.VacuumOff();
});
}
public Task DrawBackMT2571()
{
return Task.Run(() =>
{
OneStepMeasureState = State.BUSY;
Console.WriteLine("Start Drawing Back MT2571.");
if (SafeController.ManualStop)
{
Console.WriteLine("[Safe Controller]: StopAll.");
return;
}
LogicalController.MT2571Back();
while (true)
{
if (PLC.MT2571IsBack)
break;
Thread.Sleep(100);
}
Console.WriteLine("MT2571 Is Back.");
OneStepMeasureState = State.IDLE;
});
}
public Task WaitMT2571Ref()
{
return Task.Run(() =>
{
CurrentTaskName = "请轻轻推动MT2571直至找到参考点";
while(true)
{
if(MT2571.Device.RefIndexFound)
{
var init_dis = MT2571.GetDistance();
if(Math.Abs(init_dis - MT2571.InitDistance) < 200 )
break;
}
Thread.Sleep(100);
}
});
}
public Task StretchOutMT2571()
{
return Task.Run(() =>
{
double mt2571_last = 0.0;
double mt2571_current = 0.0;
double mt2571_err = 1000.0;
OneStepMeasureState = State.BUSY;
Console.WriteLine("Start Stretching MT2571.");
if (SafeController.ManualStop)
{
Console.WriteLine("[Safe Controller]: StopAll.");
return;
}
LogicalController.MT2571Out();
while (true)
{
if (PLC.MT2571IsOut)
{
//额外等一段时间,等MT2571数据稳定
Thread.Sleep(500);
mt2571_last = mt2571_current;
mt2571_current = MT2571.GetDistance();
mt2571_err = mt2571_current - mt2571_last;
if (Math.Abs(mt2571_err)<0.3)
break;
}
Thread.Sleep(100);
}
Console.WriteLine($"MT2571 Is Out, Last: {mt2571_last}, Now: {mt2571_current}");
OneStepMeasureState = State.IDLE;
});
}
/// <summary>
/// 在指定高度测一组点,阻塞
/// </summary>
/// <param name="height"></param>
private Task MeasureAtHeight(int height, int mark_index)
{
return Task.Run(() =>
{
CurrentMeasurePointIndex = mark_index;
CurrentTaskName = $"第 [{mark_index + 1}]/{TotalMeasurePoints} 个点测量中...";
Console.WriteLine(CurrentTaskName);
VacuumOn().
ContinueWith(task => DrawBackMT2571()).Result.
ContinueWith(task => LinearController.SetPosition(height)).Result.
ContinueWith(task => VacuumOff()).Result.
ContinueWith(task => StretchOutMT2571()).Result.
ContinueWith(task => DoOnePointMeasure(DataBase, mark_index)).Wait();
while(true)
{
Thread.Sleep(100);
if(OneStepMeasureState == State.FINISHED)
{
break;
}
if (SafeController.ManualStop)
{
Console.WriteLine("[Safe Controller]: StopAll.");
break;
}
}
});
}
public void MeasureTotalPoints(DataStorage data_base)
{
bool finished = false;
if(MeasureState == State.BUSY)
{
Console.WriteLine("[Measure Error]: Busy Measuring.");
return;
}
CurrentTaskName = "测量开始";
MeasureState = State.BUSY;
// 准备阶段刷新启动时间
StartTime = DateTime.Now;
Task.Run(() =>
{
CurrentMeasurePointIndex = 0;
int[] points = new int[] {
MeasureSetting.P0,
MeasureSetting.P1,
MeasureSetting.P2,
MeasureSetting.P3,
MeasureSetting.P4,
MeasureSetting.P5,
MeasureSetting.P6,
MeasureSetting.P7,
};
TotalMeasurePoints = points.Length;
DataBase = data_base;
WaitMT2571Ref().Wait();
WaitAutoLedOn().Wait();
CurrentTaskName = "顶尖下落中";
PressureController.PressPart().Wait();
DrawBackMT2571().Wait();
PrepareMeasure().Wait();
for (int i = 0; i < points.Length; i++)
MeasureAtHeight(points[i], i).Wait();
CurrentTaskName = "等待回零";
var end_task = DrawBackMT2571().
ContinueWith(task => AngleController.SetPosition(0)).
ContinueWith(task => LinearController.SetPosition(points[0])).
ContinueWith(task => PressureController.MoveUp(25));
CurrentTaskName = "等待机械归位";
while (true)
{
if (LogicalController.EncoderNearZero)
{
finished = true;
}
if (
finished &&
LinearController.State != State.BUSY &&
AngleController.State != State.BUSY &&
PressureController.State != State.BUSY
){
Console.WriteLine("All Finished");
CurrentTaskName = "测量完成";
MeasureState = State.FINISHED;
break;
}
Thread.Sleep(100);
}
});
}
private Task WaitAutoLedOn()
{
return Task.Run(() =>
{
if (OneStepMeasureState == State.BUSY)
{
Console.WriteLine("[Measure ERROR]: Busy Measuring");
return;
}
CurrentTaskName = "请长按自动启动2秒,开始测量";
Console.WriteLine("Waiting Auto Led On");
OneStepMeasureState = State.BUSY;
while(true)
{
if (IsManualStop)
{
IsManualStop = false;
Console.WriteLine("Stopped Manually.");
break;
}
if (SafeController.ManualStop)
{
Console.WriteLine("[Safe Controller]: StopAll.");
break;
}
if (PLC.AutoRunLedOn)
break;
Thread.Sleep(100);
}
EndOfOneTask(State.IDLE);
});
}
private Task PrepareMeasure()
{
return Task.Run(() =>
{
// 启动跑合
if (OneStepMeasureState == State.BUSY)
{
Console.WriteLine("[Measure ERROR]: Busy Measuring");
return;
}
CurrentTaskName = "跑合中...";
Console.WriteLine("Start Preparing, First Run Empty Loop.");
Process = 0;
OneStepMeasureState = State.BUSY;
ERM2400.Device.ClearMultiTurn(); // 清除之前积累的多圈
double StartDegree = ERM2400.Device.TotalDegrees;
PLC.SetSpeed(1, -PreMeasuringRPM);
while (true)
{
MeasureDuration = DateTime.Now - StartTime;
double deg = 0;
ERM2400.Device.ReadAngleRadians(out deg);
RelativeDegrees = deg - StartDegree;
if (RelativeDegrees >= 360)
{
Console.WriteLine($"RelativeDegrees: {RelativeDegrees}, Stop Measure.");
break;
}
if (SafeController.ManualStop)
{
Console.WriteLine("[Safe Controller]: StopAll.");
break;
}
if (IsManualStop)
{
IsManualStop = false;
Console.WriteLine("Stopped Manually.");
break;
}
Process = RelativeDegrees / MeasuringDegrees * 100;
if (Process > 100) Process = 99.9;
Thread.Sleep(100);
}
EndOfOneTask(State.IDLE);
});
}
/// <summary>
/// 测量单个点,这个仅仅是测量操作,不要单独用这个方法
/// </summary>
/// <param name="data_base">记录点的数据集</param>
/// <param name="mark_index">点的序号</param>
/// <returns></returns>
private Task DoOnePointMeasure(DataStorage data_base, int mark_index)
{
return Task.Run(() =>
{
Console.WriteLine($"Start Do Measure Task: {mark_index}");
if (OneStepMeasureState == State.BUSY)
{
Console.WriteLine("[Measure ERROR]: Busy Measuring");
return;
}
Process = 0;
OneStepMeasureState = State.BUSY;
DataBase = data_base;
ERM2400.Device.ClearMultiTurn(); // 清除之前积累的多圈
double StartDegree = ERM2400.Device.TotalDegrees;
PLC.SetSpeed(1, -MeasuringRPM);
while (true)
{
var p = new DataStorage.CurvePoint();
double deg = 0;
p.Stamp = DateTime.Now;
p.p = MT2571.GetDistance();
p.Phi = ERM2400.Device.ReadAngleRadians(out deg);
RelativeDegrees = deg - StartDegree;
p.Z = LC485.ReadLinearDis();
p.Pen1 = Easten.Device.ChannelData[2];
p.Pen2 = Easten.Device.ChannelData[3];
p.Pen3 = Easten.Device.ChannelData[4];
p.PointMark = $"P{mark_index}";
data_base.Clouds.Add(p);
MeasureDuration = DateTime.Now - StartTime;
if (RelativeDegrees >= MeasuringDegrees)
{
Console.WriteLine($"RelativeDegrees: {RelativeDegrees}, Stop Measure.");
break;
}
if (IsManualStop)
{
IsManualStop = false;
Console.WriteLine("Stopped Manually.");
break;
}
if (SafeController.ManualStop)
{
Console.WriteLine("[Safe Controller]: StopAll.");
break;
}
Process = RelativeDegrees / MeasuringDegrees * 100;
if (Process > 100) Process = 99.9;
Thread.Sleep(10);
}
PLC.SetSpeed(1, 0);
Process = 100.0;
MeasureDuration = DateTime.Now - StartTime;
OneStepMeasureState = State.FINISHED;
});
}
private void EndOfOneTask(State stop_state)
{
PLC.SetSpeed(1, 0);
Process = 100.0;
MeasureDuration = DateTime.Now - StartTime;
OneStepMeasureState = stop_state;
}
public bool CalibrateSystem(string file)
{
var handler = new CrankShaftResultHandler.ResultHandler();
handler.LoadRefrenceAndConfig(MeasureSetting.RefrenceReport);
var h = handler.ReadCSV(file)?.Deal().ReCalibration().SaveCAL();
if (h == null)
return false;
for (int i = 0; i < 4; i++)
handler.CAL.DiameterRatio[i] = 1.0;
//再计算一遍确定直径校准
handler.ReadCSV(file)?.Deal();
handler.CAL.DiameterRatio[0] = handler.Refrence.d4 / handler.Diameter0;
handler.CAL.DiameterRatio[1] = handler.Refrence.d6 / handler.Diameter1;
handler.CAL.DiameterRatio[2] = handler.Refrence.d7 / handler.Diameter2;
handler.CAL.DiameterRatio[3] = handler.Refrence.d5 / handler.Diameter3;
handler.SaveCAL();
handler.WriteCalibrationHeader(); // 校准成功在历史文件里面记录
return true;
}
public static MeasureSystem Instance
{
get
{
return instance;
}
}
}
}
1
https://gitee.com/MAMAMAisused/CrankshaftAnalysisSystem.git
git@gitee.com:MAMAMAisused/CrankshaftAnalysisSystem.git
MAMAMAisused
CrankshaftAnalysisSystem
CrankshaftAnalysisSystem
master

搜索帮助