Initial commit
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Project
|
||||
{
|
||||
public partial class StateMachine
|
||||
{
|
||||
public DateTime UpdateTime;
|
||||
private Boolean bLoop = true;
|
||||
private DateTime StepStartTime;
|
||||
private byte _messageOption;
|
||||
private Boolean _isRun;
|
||||
private System.Threading.Thread worker;
|
||||
private Boolean firstRun = false;
|
||||
public Boolean isRun { get { return _isRun; } }
|
||||
public double Loop_ms { get; set; }
|
||||
// private IMCResult MCResult = null;
|
||||
|
||||
public StateMachine()
|
||||
{
|
||||
UpdateTime = DateTime.Now;
|
||||
_messageOption = 0xFF; //모든메세지가 오도록 한다.
|
||||
worker = new System.Threading.Thread(new System.Threading.ThreadStart(Loop));
|
||||
worker.IsBackground = false;
|
||||
StepStartTime = DateTime.Parse("1982-11-23");
|
||||
Loop_ms = 0;
|
||||
}
|
||||
|
||||
//public void attachMCResult(IMCResult item)
|
||||
//{
|
||||
// MCResult = item;
|
||||
// if (GetMsgOpt(eMsgOpt.NORMAL))
|
||||
// RaiseMessage("ATTACH", string.Format("MCResult"));
|
||||
//}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
bLoop = false;
|
||||
worker.Abort();
|
||||
}
|
||||
public void Start()
|
||||
{
|
||||
worker.Start();
|
||||
}
|
||||
|
||||
void Loop()
|
||||
{
|
||||
_isRun = true;
|
||||
RaiseMessage("SM", "Start");
|
||||
while (bLoop)
|
||||
{
|
||||
|
||||
//Console.WriteLine("LOOP-START => 11111111111 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
|
||||
|
||||
|
||||
//이전업데이트타임과의 시간차를 기록한다
|
||||
Loop_ms = (DateTime.Now - UpdateTime).TotalMilliseconds;
|
||||
|
||||
UpdateTime = DateTime.Now;
|
||||
|
||||
//항상 작동하는 경우
|
||||
if (SPS != null)
|
||||
{
|
||||
//try
|
||||
//{
|
||||
SPS(this,new EventArgs());
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// Console.WriteLine("ERROR:SM:SPS:" + ex.Message);
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Console.WriteLine("LOOP-START => 2222222222 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
|
||||
|
||||
//작동스텝이 변경되었다면 그것을 알림 처리한다.
|
||||
if (getNewStep != Step)
|
||||
{
|
||||
if (GetMsgOpt(eMsgOpt.STEPCHANGE))
|
||||
RaiseMessage("SM-STEP", string.Format("Step Changed {0} >> {1}", Step, getNewStep));
|
||||
|
||||
StepApply();
|
||||
firstRun = true;
|
||||
StepStartTime = DateTime.Now;
|
||||
}
|
||||
else firstRun = false;
|
||||
|
||||
// Console.WriteLine("LOOP-START => 3333333333 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
|
||||
|
||||
//동작중에 발생하는 이벤트
|
||||
if (Running != null)
|
||||
{
|
||||
|
||||
//try
|
||||
//{
|
||||
Running(this,new RunningEventArgs(Step, firstRun, StepRunTime));
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// //오류보고는 3초에 한번씩 동작한다
|
||||
// if(Pub.GetVarRunTime(eVarTime.SMRUNERROR).TotalSeconds > 3)
|
||||
// {
|
||||
// Pub.SetVarTime(eVarTime.SMRUNERROR, DateTime.Now);
|
||||
// Pub.log.AddE("상태머신 RUN 오류:" + ex.Message);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(1);
|
||||
|
||||
// Console.WriteLine("LOOP-END => 4444444444444 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
|
||||
|
||||
}
|
||||
_isRun = false;
|
||||
if (GetMsgOpt(eMsgOpt.NORMAL)) RaiseMessage("SM", "Stop");
|
||||
}
|
||||
|
||||
|
||||
|
||||
eSMStep prebackupstepo = eSMStep.NOTSET;
|
||||
eSMStep prebackupstepn = eSMStep.NOTSET;
|
||||
public void PushStep()
|
||||
{
|
||||
prebackupstepo = OldStep;
|
||||
prebackupstepn = _step;
|
||||
}
|
||||
public void PopStep()
|
||||
{
|
||||
if (prebackupstepn != eSMStep.NOTSET)
|
||||
{
|
||||
_step = prebackupstepn;
|
||||
OldStep = prebackupstepo;
|
||||
prebackupstepn = eSMStep.NOTSET;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 상태머신의 작동상태
|
||||
/// </summary>
|
||||
public eSMStep Step { get { return _step; } }
|
||||
|
||||
/// <summary>
|
||||
/// 상태머신값을 숫자로 반환 합니다. (20이하는 시스템상태이고 그 이상은 사용자 상태)
|
||||
/// </summary>
|
||||
public byte StepValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)this._step;
|
||||
}
|
||||
}
|
||||
|
||||
public void setNewStep(eSMStep newstep_, Boolean force = false)
|
||||
{
|
||||
if (Step != newstep_) //현재스텝과 새로운 스텝이 다른경우
|
||||
{
|
||||
if (NewStep != newstep_)
|
||||
{
|
||||
if (force == false && NewStep == eSMStep.EMERGENCY && newstep_ != eSMStep.RESET)
|
||||
{
|
||||
//스텝을 변경해야하는데. 예약된 스텝이 비상정지라면 처리하지 않는다
|
||||
RaiseMessage("SM-STEP", string.Format("비상정지가 예약되어 있으므로 이 스텝({0})은 취소 됩니다", newstep_));
|
||||
}
|
||||
else
|
||||
{
|
||||
//바뀌도록 예약을 한다.
|
||||
NewStep = newstep_;
|
||||
if (GetMsgOpt(eMsgOpt.STEPCHANGE))
|
||||
RaiseMessage("SM-STEP", string.Format("Step Reserve {0} -> {1}", Step, NewStep));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//예약은 되어있는데 아직 바뀐것은 아니다.
|
||||
if (GetMsgOpt(eMsgOpt.STEPCHANGE))
|
||||
RaiseMessage("SM-STEP", string.Format("Step Already Reserve {0} -> {1}", Step, NewStep));
|
||||
}
|
||||
}
|
||||
}
|
||||
public eSMStep getNewStep
|
||||
{
|
||||
get
|
||||
{
|
||||
return NewStep;
|
||||
}
|
||||
}
|
||||
private eSMStep NewStep = eSMStep.NOTSET;
|
||||
public eSMStep OldStep = eSMStep.NOTSET; //171214
|
||||
private eSMStep _step;
|
||||
|
||||
/// <summary>
|
||||
/// newstep 의 값을 step 에 적용합니다.
|
||||
/// </summary>
|
||||
private void StepApply()
|
||||
{
|
||||
var ostep = _step;
|
||||
OldStep = _step; _step = NewStep;
|
||||
if (StepChanged != null) StepChanged(this, new StepChangeEventArgs(ostep, _step));
|
||||
} //171214
|
||||
|
||||
/// <summary>
|
||||
/// 메세지 출력옵션을 변경 합니다.
|
||||
/// </summary>
|
||||
/// <param name="opt"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SetMsgOpt(eMsgOpt opt, Boolean value)
|
||||
{
|
||||
byte pos = (byte)opt;
|
||||
if (value)
|
||||
_messageOption = (byte)(_messageOption | (1 << pos));
|
||||
else
|
||||
_messageOption = (byte)(_messageOption & ~(1 << pos));
|
||||
}
|
||||
public void SetMegOptOn() { _messageOption = 0xFF; }
|
||||
public void SetMsgOptOff() { _messageOption = 0; }
|
||||
public Boolean GetMsgOpt(eMsgOpt opt)
|
||||
{
|
||||
byte pos = (byte)opt;
|
||||
return (_messageOption & (1 << pos)) > 0;
|
||||
}
|
||||
public TimeSpan StepRunTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (StepStartTime.Year == 1982) return new TimeSpan(0);
|
||||
else return DateTime.Now - StepStartTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
153
Handler/Project_form2/Don't change it/StateMachine/_SM_RUN.cs
Normal file
153
Handler/Project_form2/Don't change it/StateMachine/_SM_RUN.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Project
|
||||
{
|
||||
public partial class fMain
|
||||
{
|
||||
#region "Common Utility"
|
||||
|
||||
/// <summary>
|
||||
/// 지정한 출력핀의 상태를 변경하고 최대 10초간 상태를 모니터링 합니다.
|
||||
/// </summary>
|
||||
/// <param name="doPin"></param>
|
||||
/// <param name="isFirst"></param>
|
||||
/// <param name="stepTime"></param>
|
||||
/// <param name="checkValue"></param>
|
||||
/// <param name="sendIntervalMs"></param>
|
||||
/// <param name="timeoutSec"></param>
|
||||
/// <returns></returns>
|
||||
bool checkDigitalO(int shutIdx, eDOName doPin, Boolean isFirst, TimeSpan stepTime, Boolean checkValue, int sendIntervalMs = 1000, int timeoutSec = 0)
|
||||
{
|
||||
|
||||
//eIOCheckResult result = eIOCheckResult.Complete;
|
||||
var retval = false;
|
||||
if (timeoutSec == 0) timeoutSec = Pub.setting.Timeout_DIOCommand;
|
||||
|
||||
if (isFirst)
|
||||
{
|
||||
Pub.Result.doCheckTime[shutIdx, (int)doPin] = DateTime.Now.AddDays(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//지정한 출력핀이 조건에 맞지 않을 경우ㅍ
|
||||
var curValue = Util_DO.GetIOOutput(doPin);
|
||||
if (curValue != checkValue)
|
||||
{
|
||||
//Offt신호는 1초에 1번씩 전송하게 한다.
|
||||
var ts = DateTime.Now - Pub.Result.doCheckTime[shutIdx, (int)doPin];
|
||||
if (ts.TotalMilliseconds >= sendIntervalMs)
|
||||
{
|
||||
Pub.dio.SetOutput((int)doPin, checkValue);
|
||||
Pub.Result.doCheckTime[shutIdx, (int)doPin] = DateTime.Now;
|
||||
}
|
||||
|
||||
//전체 시간이 10초를 넘어가면 오류로 처리함
|
||||
if (stepTime.TotalSeconds >= timeoutSec)
|
||||
Pub.Result.SetResultTimeOutMessage(doPin, checkValue, eNextStep.pause);
|
||||
}
|
||||
else retval = true;
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool checkDigitalO(int shutIdx, eDIName doPin, Boolean isFirst, TimeSpan stepTime, Boolean checkValue, int timeoutSec = 0)
|
||||
{
|
||||
//eIOCheckResult result = eIOCheckResult.Complete;
|
||||
var retval = false;
|
||||
if (timeoutSec == 0) timeoutSec = (int)Pub.setting.Timeout_DIOCommand;
|
||||
|
||||
//지정한 출력핀이 조건에 맞지 않을 경우ㅍ
|
||||
var curValue = Util_DO.GetIOInput(doPin);
|
||||
if (curValue != checkValue)
|
||||
{
|
||||
//전체 시간이 10초를 넘어가면 오류로 처리함
|
||||
//var diRunTime = DateTime.Now - Pub.Result.diCheckTime[shutIdx, (int)doPin];
|
||||
if (stepTime.TotalSeconds >= timeoutSec)
|
||||
{
|
||||
//result = eIOCheckResult.Timeout;
|
||||
Pub.Result.SetResultTimeOutMessage(doPin, checkValue, eNextStep.pause);
|
||||
}
|
||||
}
|
||||
else retval = true;
|
||||
return retval;
|
||||
}
|
||||
|
||||
Boolean CheckMotionPos(int seqIdx, eAxis Motaxis, TimeSpan stepTime, double pos, double speed, double acc, double dcc, string source, Boolean useInterLocak=true, int timeoutSec = 0)
|
||||
{
|
||||
var axis = (int)Motaxis;
|
||||
|
||||
//타임아웃 적용 191213
|
||||
if (timeoutSec == 0) timeoutSec = Pub.setting.Timeout_MotionCommand;
|
||||
|
||||
|
||||
//X축을 그립위치까지 이동함
|
||||
if (Pub.mot.isINP[axis] && Pub.mot.isMotion[axis] == false)
|
||||
{
|
||||
var offset = Math.Abs(Pub.mot.dCMDPOS[axis] - pos);
|
||||
var offsetReal = Math.Abs(Pub.mot.dCMDPOS[axis] - Pub.mot.dACTPOS[axis]);
|
||||
if (offset > 0.01 || offsetReal > 0.1)
|
||||
{
|
||||
|
||||
if (Util_Mot.Move(Motaxis, pos, speed, acc, false, true, useInterLocak) == false)
|
||||
Console.WriteLine("move error {0},pos={1} => {2}",Motaxis,pos,Pub.mot.errorMessage);
|
||||
|
||||
|
||||
//모션을 옴겨야하는 상황인데 최대시간을 초과했다면 오류로 처리한다
|
||||
if (timeoutSec != -1 && stepTime.TotalSeconds >= timeoutSec)
|
||||
{
|
||||
Pub.Result.SetResultTimeOutMessage(Motaxis, eECode.MOT_CMD, eNextStep.pause, source);
|
||||
}
|
||||
|
||||
//모션을 이동시켰으니 False 처리한다
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
|
||||
//축이 이동중이면 처리하지 않는다.
|
||||
if (Pub.mot.isINP[axis] == false || Pub.mot.isMotion[axis] == true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//X축실위치값 확인
|
||||
if (Util_Mot.getPositionMatch(axis, pos) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 시간만큼 대기하며 완료되면 true를 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
Boolean WaitForSeconds(eWaitType wait, double timems)
|
||||
{
|
||||
var idx = (byte)wait;
|
||||
if (Pub.Result.WaitForVar[idx] == null || Pub.Result.WaitForVar[idx].Year == 1982)
|
||||
{
|
||||
Pub.Result.WaitForVar[idx] = Pub.Result.WaitForVar[idx] = DateTime.Now;
|
||||
//Pub.log.Add(string.Format("Wait for [{0}], Wait Time:{1}ms", wait, timems));
|
||||
}
|
||||
var ts = DateTime.Now - Pub.Result.WaitForVar[idx];
|
||||
if (ts.TotalSeconds >= timems) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
void ResetWaitForSeconds(eWaitType wait)
|
||||
{
|
||||
var idx = (byte)wait;
|
||||
Pub.Result.WaitForVar[idx] = DateTime.Parse("1982-11-23");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}//cvass
|
||||
}
|
||||
Reference in New Issue
Block a user