Files
CMS-MTConn/MTC_Sim/MTC_Sim/CMS_MachineSim.cs
T
2016-04-27 16:28:36 +02:00

846 lines
26 KiB
C#

/*
* Copyright Copyright 2016, Steamware s.r.l. & CMS s.p.a.
*
* Based on data, code and example by MTC consortium & System Insights, Inc.
*
* */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MTC_Sim
{
using MTConnect;
using System.Configuration;
using System.Diagnostics;
using System.IO;
public partial class CMS_MachineSim : Form
{
/// <summary>
/// Oggetto x gestione dell'adapter GENERICO (x poter usare metodi di ognuno...)
/// </summary>
AdapterGeneric agObj;
/// <summary>
/// configurazione caricata
/// </summary>
AdapterConf adpConf;
/// <summary>
/// tipo di adapter prescelto...
/// </summary>
protected tipoAdapter tipoScelto = tipoAdapter.Demo;
#region utils ed helpers
public static void EnableTab(TabPage page, bool enable)
{
EnableControls(page.Controls, enable);
}
private static void EnableControls(Control.ControlCollection ctls, bool enable)
{
foreach (Control ctl in ctls)
{
ctl.Enabled = enable;
EnableControls(ctl.Controls, enable);
}
}
private class Item
{
public string Name;
public int Value;
public Item(string name, int value)
{
Name = name; Value = value;
}
}
#endregion
public CMS_MachineSim()
{
InitializeComponent();
// inizio con tab control disabilitati
EnableTab(tabCtrlMain.TabPages[1], false);
EnableTab(tabCtrlMain.TabPages[2], false);
// definisco tipo adapter in base a selezione: FARE, x ora blindato...
tipoScelto = tipoAdapter.ND;
adpConf = new AdapterConf();
loadAdapterType();
}
/// <summary>
/// carica adapter richiesto
/// </summary>
private void loadAdapterType()
{
switch (tipoScelto)
{
case tipoAdapter.Demo:
agObj = new AdapterDemo(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], true);
break;
case tipoAdapter.Fanuc:
agObj = new AdapterFanuc(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], true);
EnableTab(tabCtrlMain.TabPages[2], false);
break;
case tipoAdapter.HMI:
case tipoAdapter.ND:
default:
agObj = new AdapterDemo(this, adpConf);
EnableTab(tabCtrlMain.TabPages[1], false);
EnableTab(tabCtrlMain.TabPages[2], false);
break;
}
lblCurrAdapt.Text = string.Format("Adapter loaded: {0}", tipoScelto.ToString().ToUpper());
// carico i default values su interfaccia
setDefaults();
}
/// <summary>
/// impostazione valori defaults
/// </summary>
private void setDefaults()
{
stop.Enabled = false;
dump.Enabled = false;
D1_NAME.Text = utils.CRS("D1_NAME");
D1_ID.Text = utils.CRS("D1_ID");
D1_UUID.Text = utils.CRS("D1_UUID");
program.Text = utils.CRS("D1_PROGRAM");
PROG_ROW_NUM.Text = "0";
partID.Text = utils.CRS("PartID");
pzOk = 0;
pzKo = 0;
Power = 1000;
AccTime = 1440 * 365;
OPERATOR_ID.Text = "M9999";
STATUS_PLC_ADP.Text = utils.binaryForm(utils.CRI("STATUS_PLC_ADP"));
STATUS_ADP_PLC.Text = utils.binaryForm(utils.CRI("STATUS_ADP_PLC"));
MainProgrBar.Minimum = 0;
MainProgrBar.Maximum = 6;
MainProgrBar.Value = 0;
MainProgrBar.Step = 1;
// compilo combobox causali fermo...
string[] contenuto = File.ReadAllLines("HaltTypeList.txt");
System.Collections.Generic.Dictionary<string, string> comboSource = new Dictionary<string, string>();
foreach (var line in contenuto)
{
// se la linea non è commento e non è vuota...
if (line.Length > 0 && line[0] != '#')
{
string[] tokens = line.Split(':');
comboSource.Add(tokens[0], tokens[1]);
//riga.value = tokens[0];
//riga.label = tokens[1];
//functionalMode.Items.Add(new { Value = riga.label, Key = riga.value });
//functionalMode.Items.Add(new { label = tokens[1], value = tokens[0] });
}
}
functionalMode.DataSource = new BindingSource(comboSource, null);
functionalMode.DisplayMember = "Value";
functionalMode.ValueMember = "Key";
string[] row = { "0", "0", "0", "0", "0", "0" };
PosAct.Rows.Add(row);
// fix componenti vettoriali PATH, UNOP, ASSI...
for (int i = 0; i < adpConf.nPath; i++)
{
cbPathSel.Items.Insert(i, adpConf.Path[i].alias);
}
if (adpConf.nPath > 0) cbPathSel.SelectedIndex = 0;
for (int i = 0; i < adpConf.nUnOp; i++)
{
//cbAxNum.Items.Insert(i, adpConf.Axis[i].alias);
}
//if (adpConf.nUnOp > 0) cbAxNum.SelectedIndex = 0;
for (int i = 0; i < adpConf.nAxis; i++)
{
cbAxNum.Items.Insert(i, adpConf.Axis[i].alias);
}
if (adpConf.nAxis > 0) cbAxNum.SelectedIndex = 0;
}
/// <summary>
/// Avvio dell'adapter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void start_Click(object sender, EventArgs e)
{
int porta = Convert.ToInt32(port.Text);
agObj.startAdapter(porta);
// fix buttons start/stop/dump
start.Enabled = false;
stop.Enabled = true;
dump.Enabled = true;
// Start timer periodico
gather.Interval = utils.CRI("timerInt");
gather.Enabled = true;
}
/// <summary>
/// fermata dell'adapter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void stop_Click(object sender, EventArgs e)
{
agObj.stopAdapter();
stop.Enabled = false;
dump.Enabled = false;
start.Enabled = true;
gather.Enabled = false;
}
private void gather_Tick(object sender, EventArgs e)
{
MainProgrBar.PerformStep();
// eseguo eventuali simulazioni x dati/flags
simulateData();
MainProgrBar.PerformStep();
// avvio fase raccolta dati e invio con adapter
agObj.gaterAndSend();
MainProgrBar.PerformStep();
// refresh stringhe code M/S/T
refreshCodeMST();
MainProgrBar.PerformStep();
// se è arrivato a 100 resetto...
if (MainProgrBar.Value >= MainProgrBar.Maximum) MainProgrBar.Value = 0;
}
private void message_Leave(object sender, EventArgs e)
{
agObj.mMessage.Code = messageCode.Text;
agObj.mMessage.Value = messageText.Text;
agObj.mMessage.ForceChanged();
agObj.mAdapter.SendChanged();
}
private void ERR_00_CheckedChanged(object sender, EventArgs e)
{
if (ERR_00.Checked)
((AdapterDemo)agObj).mFillLevel.Add(Condition.Level.WARNING, "ERR_00 Coolant Low", "COOL", "LOW");
else
((AdapterDemo)agObj).mFillLevel.Clear("COOL");
agObj.mAdapter.SendChanged();
}
// apro eseguibile dump
private void dump_Click(object sender, EventArgs e)
{
string path = Application.StartupPath;
Process.Start(string.Format(@"{0}\..\..\dump\dump.exe", path));
}
#region classi x simulazione valori vari
/// <summary>
/// simula alcuni dati generando ad esempio numeri casuali... SE abilitato e SE adapter è DEMO
/// </summary>
private void simulateData()
{
if (enableDataSim.Checked && tipoScelto == tipoAdapter.Demo)
{
DateTime adesso = DateTime.Now;
Random rnd = new Random();
if (rnd.Next(0, 100) > 90)
{
PROG_ROW_NUM.Text = rnd.Next(1, 10000).ToString();
}
// ora controllo se ci siano eventi M/S/T x alzare flag...
if (agObj.codaM.Count > 0) agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.M_CODE;
if (agObj.codaS.Count > 0) agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.S_CODE;
if (agObj.codaT.Count > 0) agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.T_CODE;
// aggiungo 1 pz al totale nel 33% dei casi (-->TC circa 3 x tick)...
if (rnd.Next(0, 100) > 67)
{
pzOk++;
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.PZ_OK;
}
// cambio posizioni XYZ/ijk nel 20% dei casi x ogni terna...
if (rnd.Next(0, 100) > 80)
{
PosAct.Rows[0].Cells[0].Value = rnd.Next(0, 100);
PosAct.Rows[0].Cells[1].Value = rnd.Next(0, 100);
PosAct.Rows[0].Cells[2].Value = rnd.Next(0, 100);
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.POS_ACT;
}
if (rnd.Next(0, 100) > 80)
{
PosAct.Rows[0].Cells[3].Value = rnd.Next(0, 100);
PosAct.Rows[0].Cells[4].Value = rnd.Next(0, 100);
PosAct.Rows[0].Cells[5].Value = rnd.Next(0, 100);
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.POS_ACT;
}
// cambio power nel 25% dei casi...
if (rnd.Next(0, 100) > 75)
{
Power += rnd.Next(-10, 10);
}
// aggiungo 1 min AccTime nel 1.6% dei casi
if (rnd.Next(0, 1000) > 984)
{
AccTime++;
}
// controllo se ci sia il flag di lettura di un evento M/S/T nel qual caso lo abbasso...
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.M_CODE))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.M_CODE)) agObj.STROBE_PLC -= Strobe.M_CODE;
}
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.S_CODE))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.S_CODE)) agObj.STROBE_PLC -= Strobe.S_CODE;
}
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.T_CODE))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.T_CODE)) agObj.STROBE_PLC -= Strobe.T_CODE;
}
// controllo se ci sia il flag di lettura di un evento pz ok/ko nel qual caso lo abbasso...
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.PZ_OK))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.PZ_OK)) agObj.STROBE_PLC -= Strobe.PZ_OK;
}
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.PZ_KO))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.PZ_KO)) agObj.STROBE_PLC -= Strobe.PZ_KO;
}
// controllo se ci sia il flag di lettura di un evento FEED_SPEED nel qual caso lo abbasso...
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.FEED_SPEED))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.FEED_SPEED)) agObj.STROBE_PLC -= Strobe.FEED_SPEED;
}
// controllo se ci sia il flag di lettura di un evento POS_ACT nel qual caso lo abbasso...
if (utils.IsSetAll(agObj.STROBE_ADP, Strobe.POS_ACT))
{
if (utils.IsSetAll(agObj.STROBE_PLC, Strobe.POS_ACT)) agObj.STROBE_PLC -= Strobe.POS_ACT;
}
// aggiorno visualizzazione strobe!
STATUS_PLC_ADP.Text = utils.binaryForm((int)agObj.STROBE_PLC);
STATUS_ADP_PLC.Text = utils.binaryForm((int)agObj.STROBE_ADP);
}
}
/// <summary>
/// aggiorna visualizzazione code...
/// </summary>
private void refreshCodeMST()
{
lblCodaM.Text = string.Join(",", agObj.codaM.ToArray());
lblCodaT.Text = string.Join(",", agObj.codaT.ToArray());
lblCodaS.Text = string.Join(",", agObj.codaS.ToArray());
}
private void accodaCodM()
{
if (addCodM.Text.Trim() != "")
{
agObj.codaM.Add(addCodM.Text.Trim());
addCodM.Text = "";
}
refreshCodeMST();
}
private void accodaCodS()
{
if (addCodS.Text.Trim() != "")
{
agObj.codaS.Add(addCodS.Text.Trim());
addCodS.Text = "";
}
refreshCodeMST();
}
private void accodaCodT()
{
if (addCodT.Text.Trim() != "")
{
agObj.codaT.Add(addCodT.Text.Trim());
addCodT.Text = "";
}
refreshCodeMST();
}
private void addCodM_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// accodo testo
accodaCodM();
}
else if (e.KeyCode == Keys.Escape)
{
// svuoto!
addCodM.Text = "";
}
}
private void addCodM_Leave(object sender, EventArgs e)
{
accodaCodM();
}
private void addCodS_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// accodo testo
accodaCodS();
}
else if (e.KeyCode == Keys.Escape)
{
// svuoto!
addCodS.Text = "";
}
}
private void addCodS_Leave(object sender, EventArgs e)
{
accodaCodS();
}
private void addCodT_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// accodo testo
accodaCodT();
}
else if (e.KeyCode == Keys.Escape)
{
// svuoto!
addCodT.Text = "";
}
}
private void addCodT_Leave(object sender, EventArgs e)
{
accodaCodT();
}
#endregion
private void txtPathFeed_TextChanged(object sender, EventArgs e)
{
hsPathFeed.Value = Convert.ToInt32(txtPathFeed.Text);
}
private void txtPathFeedOver_TextChanged(object sender, EventArgs e)
{
hsPathFeedOver.Value = Convert.ToInt32(txtPathFeedOver.Text);
}
private void txtPathSpeedOver_TextChanged(object sender, EventArgs e)
{
hsPathSpeedOver.Value = Convert.ToInt32(txtPathSpeedOver.Text);
}
private void raiseFlag_FEED_SPEED()
{
// se non c'è flag lo alzo...
if (!utils.IsSetAll(agObj.STROBE_PLC, Strobe.FEED_SPEED))
{
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.FEED_SPEED;
}
}
private void hsPathFeed_ValueChanged(object sender, EventArgs e)
{
txtPathFeed.Text = hsPathFeed.Value.ToString();
raiseFlag_FEED_SPEED();
}
private void hsPathFeedOver_ValueChanged(object sender, EventArgs e)
{
txtPathFeedOver.Text = hsPathFeedOver.Value.ToString();
raiseFlag_FEED_SPEED();
}
private void hsPathSpeedOver_ValueChanged(object sender, EventArgs e)
{
txtPathSpeedOver.Text = hsPathSpeedOver.Value.ToString();
raiseFlag_FEED_SPEED();
}
#region gestione load conf
private void mConfGen_Click(object sender, EventArgs e)
{
SetupAdapter setupWIndow = new SetupAdapter();
setupWIndow.Show(this);
}
/// <summary>
/// Percorso file completo
/// </summary>
protected string filePath(string fileName)
{
return string.Format("{0}/{1}", utils.CRS("adapterConfPath"), fileName);
}
private void mLoadAdaptConf_Click(object sender, EventArgs e)
{
// mostro selettore file x leggere adapter..
OpenFileDialog openFileDial = new OpenFileDialog();
// directory iniziale
openFileDial.InitialDirectory = utils.CRS("adapterConfPathFull");
// Set filter options and filter index.
openFileDial.Filter = "XML Files (.xml)|*.xml|All Files (*.*)|*.*";
openFileDial.FilterIndex = 1;
// altre opzioni
openFileDial.Multiselect = false;
// Call the ShowDialog method to show the dialog box.
DialogResult userClickedOK = openFileDial.ShowDialog();
// Process input if the user clicked OK.
if (userClickedOK == DialogResult.OK)
{
// Read the configuration object from a file
adpConf = AdapterConf.Deserialize(openFileDial.FileName);
// indico quale sia il tipo di adapter
tipoScelto = adpConf.TipoAdapt;
loadAdapterType();
// carico file XML in web browser...
wbXmlConf.DocumentText = AdapterConf.rawXml(openFileDial.FileName);
// avvio macchina con adapter specificato...
//agObj
}
}
#endregion
#region accesso dati produzione FROM/TO maschera
/// <summary>
/// Dati di produzione (su form)
/// </summary>
public prodData datiProd
{
get
{
prodData answ = new prodData();
// carico da form
answ.ProgramName = program.Text;
answ.ProgrRow = PROG_ROW_NUM.Text;
answ.PartId = partID.Text;
answ.Operator = OPERATOR_ID.Text;
// variabili lette da + controlli
answ.Status = stop.Enabled;
answ.Power = Power;
answ.AccTime = AccTime;
answ.EmrStop = estop.Checked;
if (automatic.Checked) answ.RunMode = "AUTOMATIC";
else if (mdi.Checked) answ.RunMode = "MANUAL_DATA_INPUT";
else if (edit.Checked) answ.RunMode = "EDIT";
else answ.RunMode = "MANUAL";
if (running.Checked) answ.ExeMode = "ACTIVE";
else if (feedhold.Checked) answ.ExeMode = "FEED_HOLD";
else if (stopped.Checked) answ.ExeMode = "STOPPED";
else if (ready.Checked) answ.ExeMode = "READY";
answ.FuncMode = ((KeyValuePair<string, string>)functionalMode.SelectedItem).Key;
answ.MessageCode = messageCode.Text;
answ.MessageText = messageText.Text;
// pezzi
answ.pzOk = pzOk;
answ.pzKo = pzKo;
answ.pzTot = pzOk + pzKo;
// allarmi...
answ.err_01 = ERR_01.Checked;
answ.err_02 = ERR_02.Checked;
answ.err_03 = ERR_03.Checked;
answ.err_04 = ERR_04.Checked;
answ.err_05 = ERR_05.Checked;
answ.err_06 = ERR_06.Checked;
// ritorno oggetto!
return answ;
}
}
private void pzKo_TextChanged(object sender, EventArgs e)
{
agObj.STROBE_PLC = agObj.STROBE_PLC | Strobe.PZ_KO;
txtPzTot.Text = pzTot.ToString();
}
protected int Power
{
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtPower.Text.Trim());
}
catch
{ }
return answ;
}
set
{
txtPower.Text = value.ToString();
}
}
protected int AccTime
{
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtAccTime.Text.Trim());
}
catch
{ }
return answ;
}
set
{
txtAccTime.Text = value.ToString();
}
}
protected int pzOk
{
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtPzOk.Text.Trim());
}
catch
{ }
return answ;
}
set
{
txtPzOk.Text = value.ToString();
txtPzTot.Text = pzTot.ToString();
}
}
protected int pzKo
{
get
{
int answ = 0;
try
{
answ = Convert.ToInt32(txtPzKo.Text.Trim());
}
catch
{ }
return answ;
}
set
{
txtPzKo.Text = value.ToString();
txtPzTot.Text = pzTot.ToString();
}
}
protected int pzTot
{
get
{
return pzOk + pzKo;
}
}
#endregion
#region gestione Path
/// <summary>
/// Dati PATH
/// </summary>
public PathData CurrPath
{
get
{
PathData answ = new PathData();
answ.PathSel = cbPathSel.SelectedIndex;
// FEED/SPEED
answ.PathFeedrate = hsPathFeed.Value;
answ.PathFeedrateOver = hsPathFeedOver.Value;
answ.PathSpeedrateOver = hsPathSpeedOver.Value;
// posizione attuale
position posAct = new position();
DataGridViewCellCollection cells = PosAct.Rows[0].Cells;
float.TryParse(cells[0].Value.ToString(), out posAct.x);
float.TryParse(cells[1].Value.ToString(), out posAct.y);
float.TryParse(cells[2].Value.ToString(), out posAct.z);
float.TryParse(cells[3].Value.ToString(), out posAct.i);
float.TryParse(cells[4].Value.ToString(), out posAct.j);
float.TryParse(cells[5].Value.ToString(), out posAct.k);
answ.PathPosAct = posAct;
// ritorno oggetto!
return answ;
}
}
#endregion
#region gestione UnOp
#endregion
#region gestione assi
private void cbAxNum_SelectedIndexChanged(object sender, EventArgs e)
{
// aggiorna visualizzazione asse... imposto valori standard x controlli
AxMainProc.Text = "1";
AxIsMaster.Checked = false;
AxMastId.Text = "0";
cbAxType.SelectedIndex = 0;
AxDir.Text = "1";
AxLoad.Value = 50;
AxPosition.Value = 50;
AxFeedAct.Value = 50;
AxFeedOver.Value = 100;
AxAccelAct.Text = "0";
AxAccTime.Text = "0";
AxBatt.Text = "100";
}
/// <summary>
/// Dati di produzione (su form)
/// </summary>
public AxisData CurrAxis
{
get
{
Random rnd = new Random();
AxisData answ = new AxisData();
answ.AxisSel= cbAxNum.SelectedIndex;
answ.AxisMainProc = AxMainProc.Text;
answ.AxisIsMaster = AxIsMaster.Checked;
answ.AxisMastId = AxMastId.Text;
answ.AxisType = AxisType;
answ.AxisDir = AxDir.Text;
answ.AxisLoad = AxLoad.Value;
answ.AxisPosAct = AxPosition.Value + rnd.Next(-2, 2);
answ.AxisPosTgt = AxPosition.Value;
answ.AxisFeedAct = AxFeedAct.Value;
answ.AxisFeedOver = AxFeedOver.Value;
answ.AxisAccel = AxAccelAct.Text;
answ.AxisAccTime = AxAccTime.Text;
answ.AxisBattery = AxBatt.Text;
// restituisco oggetto
return answ;
}
}
protected string AxisType
{
get
{
string answ = "";
try
{
answ = cbAxType.SelectedItem.ToString(); ;
}
catch
{ }
return answ;
}
}
private void xLoad_Scroll(object sender, ScrollEventArgs e)
{
AxLoadValue.Text = AxLoad.Value.ToString();
}
private void xPosition_Scroll(object sender, ScrollEventArgs e)
{
#if false
agObj.mPosition.Value = xPosition.Value;
agObj.mAdapter.SendChanged();
#endif
AxPositionValue.Text = AxPosition.Value.ToString();
}
private void cLoad_Scroll(object sender, ScrollEventArgs e)
{
AxFeedActValue.Text = AxFeedAct.Value.ToString();
}
private void cSpeed_Scroll(object sender, ScrollEventArgs e)
{
#if false
agObj.mSpeed.Value = cSpeed.Value;
agObj.mAdapter.SendChanged();
#endif
AxFeedOverValue.Text = AxFeedOver.Value.ToString();
}
#endregion
}
}