UniCB cleanup, simulation improved, locking.
This commit is contained in:
@@ -83,57 +83,14 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
const int BUFFER_SIZE = 4000; /// Size of input buffers
|
const int BUFFER_SIZE = 4000; /// Size of input buffers
|
||||||
byte[] buffer; /// Buffer for data received in one attempt in RunDeviceBefore()
|
byte[] buffer; /// Buffer for data received in one attempt in RunDeviceBefore()
|
||||||
byte[] rcvdData; /// Buffer for all recevied but nut processed data. May contain data from several read attempts
|
byte[] rcvdData; /// Buffer for all recevied but nut processed data. May contain data from several read attempts
|
||||||
int[] cumulativeSums;
|
int[] cumulativeSums; /// Cumulative sums to verify checksums easily
|
||||||
int rcvdBytesCount; /// Count of valid bytes in rcvdData buffer
|
int rcvdBytesCount; /// Count of valid bytes in rcvdData buffer
|
||||||
int lastReceivedTime; /// StateMachine.Time time stamp of the last received valid frame
|
int lastReceivedTime; /// StateMachine.Time time stamp of the last received valid frame
|
||||||
|
bool outputsInitialized; /// Flag indicating that outputs were sent at least once
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Route / digital outputs / states of electromagnetic valves
|
|
||||||
///
|
|
||||||
readonly UInt128 routeMask; /// Set in the constructor, bits of outputs that can be controlled by Action.ChangeRoute are set.
|
|
||||||
/// Regulation valve control outputs and diverters cannot be controlled by Action.ChangeRoute
|
|
||||||
/// Depends on the control board configuration
|
|
||||||
|
|
||||||
ulong valvesToInvert; /// From configurations of valve and pump components. Inversion is applied when creating
|
|
||||||
/// Action.ChangeRoute an dafter obtaining RRoute from the control board
|
|
||||||
|
|
||||||
/// State of digital outputs obtained from the control board
|
|
||||||
public UInt128 RRoute
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ((StateMachine.Time - lastReceivedTime) < 5)
|
|
||||||
{
|
|
||||||
return (UInt128)(Data.Vystupy ^ valvesToInvert);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ((UInt128)1) << cbCfg.BitNr; /// No connection to control board
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt128 displayedRoute; /// A route displayed on the screen (inversions are not applied)
|
|
||||||
UInt128 bitsChangedByUI; /// Ones in this word indicate which valves/pumpes were changed in UI by mouse clicks
|
|
||||||
UInt128 displayedRoutePlusUI; /// A route displayed on the screen plus the modifications from UI (inversions are not applied)
|
|
||||||
UInt128 outputLatch; /// A copy of route sent to physical outputs
|
|
||||||
UInt128 benchModelRoute;
|
|
||||||
bool outputsInitialized;
|
|
||||||
int lastStateMachineTime = 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Route: 128-bit word representing the current state of all valves and pumps
|
|
||||||
/// </summary>
|
|
||||||
public UInt128 Route { get { return benchModelRoute; } }
|
|
||||||
|
|
||||||
|
|
||||||
/// UI actions are blocked when true
|
|
||||||
public bool IsUIBlocked { get; set; }
|
|
||||||
|
|
||||||
/// Message queue
|
|
||||||
Queue<Action> actionQueue;
|
|
||||||
|
|
||||||
/// Received data
|
/// Received data
|
||||||
|
///
|
||||||
public GeneralData Data;
|
public GeneralData Data;
|
||||||
DivTransitionData divTransitionData;
|
DivTransitionData divTransitionData;
|
||||||
ScopeAnalyzerData scopeAnalyzerData;
|
ScopeAnalyzerData scopeAnalyzerData;
|
||||||
@@ -143,7 +100,7 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
|
|
||||||
/// Current flow meter ID
|
/// Current flow meter ID
|
||||||
public int FlowmeterId { get { return Convert.ToInt32(Data.State & (ulong)StatusP.FlowmtrNrMask); } }
|
public int FlowmeterId { get { return Convert.ToInt32(Data.State & (ulong)StatusP.FlowmtrNrMask); } }
|
||||||
|
|
||||||
public UInt64 DigitalInputs { get { return Data.Vstupy; } } /// Digital inputs
|
public UInt64 DigitalInputs { get { return Data.Vstupy; } } /// Digital inputs
|
||||||
|
|
||||||
public Int16 AnalogInput(int channel)
|
public Int16 AnalogInput(int channel)
|
||||||
@@ -152,10 +109,36 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
{
|
{
|
||||||
return Data.AnalogInput[channel];
|
return Data.AnalogInput[channel];
|
||||||
}
|
}
|
||||||
return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Values valid during a test
|
///
|
||||||
|
/// Digital outputs / Route / States of electromagnetic valves
|
||||||
|
///
|
||||||
|
readonly UInt128 routeMask; /// Set in the constructor, bits of outputs that can be controlled by Action.ChangeRoute are set.
|
||||||
|
/// Regulation valve control outputs and diverters cannot be controlled by Action.ChangeRoute
|
||||||
|
/// Depends on the control board configuration
|
||||||
|
ulong valvesToInvert; /// From configurations of valve and pump components. Inversion is applied when creating
|
||||||
|
/// a message to be sent by serial port
|
||||||
|
UInt128 displayedRoute; /// A route displayed on the screen (inversions are not applied)
|
||||||
|
UInt128 bitsChangedByUI; /// Ones in this word indicate which valves/pumpes were changed in UI by mouse clicks
|
||||||
|
UInt128 displayedRoutePlusUI; /// A route displayed on the screen plus the modifications from UI (inversions are not applied)
|
||||||
|
UInt128 outputLatch; /// A copy of data sent to physical digital outputs (inversions are not applied)
|
||||||
|
///
|
||||||
|
/// 128-bit word representing the current state of all valves and pumps (inversions are not applied)
|
||||||
|
///
|
||||||
|
UInt128 route;
|
||||||
|
public UInt128 Route { get { return route; } }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Queue of higher level commands for the control board
|
||||||
|
///
|
||||||
|
Queue<Action> actionQueue;
|
||||||
|
|
||||||
|
/// UI actions are blocked when true
|
||||||
|
public bool IsUIBlocked { get; set; }
|
||||||
|
|
||||||
|
/// Measured values valid during a test
|
||||||
public double RefFrequency { get { return Data.ReferenceFreq[0]; } }
|
public double RefFrequency { get { return Data.ReferenceFreq[0]; } }
|
||||||
public double RefFrequency1 { get { return Data.ReferenceFreq[1]; } }
|
public double RefFrequency1 { get { return Data.ReferenceFreq[1]; } }
|
||||||
public double RefFrequency2 { get { return Data.ReferenceFreq[2]; } }
|
public double RefFrequency2 { get { return Data.ReferenceFreq[2]; } }
|
||||||
@@ -252,19 +235,14 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
|
|
||||||
/// Handler handling mouse clicks on the schematc drawinng - valve or pump state changes
|
/// Handler handling mouse clicks on the schematc drawinng - valve or pump state changes
|
||||||
TBF.UiBridge.Bridge.RouteChangeHandler += delegate(object sndr, TBF.UiBridge.RouteChangeArgs args)
|
TBF.UiBridge.Bridge.RouteChangeHandler += delegate(object sndr, TBF.UiBridge.RouteChangeArgs args)
|
||||||
{
|
{
|
||||||
UInt128 oneBitMask = ((UInt128)1) << args.BitNr;
|
UInt128 oneBitMask = ((UInt128)1) << args.BitNr;
|
||||||
bitsChangedByUI |= oneBitMask;
|
lock (this)
|
||||||
displayedRoutePlusUI = displayedRoutePlusUI ^ oneBitMask;
|
{
|
||||||
//if ((displayedRoutePlusUI & oneBitMask) == 0)
|
bitsChangedByUI |= oneBitMask;
|
||||||
//{
|
displayedRoutePlusUI = displayedRoutePlusUI ^ oneBitMask;
|
||||||
// displayedRoutePlusUI |= oneBitMask;
|
}
|
||||||
//}
|
};
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// displayedRoutePlusUI &= (~oneBitMask);
|
|
||||||
//}
|
|
||||||
};
|
|
||||||
|
|
||||||
log.FatalFormat("{0} - Device successfully initialized", Name);
|
log.FatalFormat("{0} - Device successfully initialized", Name);
|
||||||
}
|
}
|
||||||
@@ -274,6 +252,9 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void RunDeviceBefore()
|
public void RunDeviceBefore()
|
||||||
{
|
{
|
||||||
|
///
|
||||||
|
/// Read data from the control board
|
||||||
|
///
|
||||||
if (cbCfg.DebugLevel == DebugMode.Normal && serialPort != null && serialPort.IsOpen)
|
if (cbCfg.DebugLevel == DebugMode.Normal && serialPort != null && serialPort.IsOpen)
|
||||||
{
|
{
|
||||||
/// Read new received bytes and append them to a buffer
|
/// Read new received bytes and append them to a buffer
|
||||||
@@ -357,15 +338,25 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
rcvdBytesCount -= lastValidOffset;
|
rcvdBytesCount -= lastValidOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
benchModelRoute = RRoute;
|
|
||||||
///
|
///
|
||||||
if (!IsUIBlocked && bitsChangedByUI != 0)
|
/// Combine data from the current route, from digital outputs and from UI
|
||||||
|
///
|
||||||
|
lock (this)
|
||||||
{
|
{
|
||||||
benchModelRoute = (benchModelRoute & ~bitsChangedByUI) | (displayedRoutePlusUI & bitsChangedByUI);
|
route = (UInt128)(Data.Vystupy ^ valvesToInvert);
|
||||||
bitsChangedByUI = 0;
|
///
|
||||||
|
if (!IsUIBlocked && bitsChangedByUI != 0)
|
||||||
|
{
|
||||||
|
route = (route & ~bitsChangedByUI) | (displayedRoutePlusUI & bitsChangedByUI);
|
||||||
|
bitsChangedByUI = 0;
|
||||||
|
}
|
||||||
|
if ((StateMachine.Time - lastReceivedTime) >= 5)
|
||||||
|
{
|
||||||
|
/// No connection to control board ... set indicator bit
|
||||||
|
route += ((UInt128)1) << cbCfg.BitNr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
log.DebugFormat("Route synced with RRoute and UI changes, new route = {0}", Utils.RouteToStr(route));
|
||||||
log.DebugFormat("Route synced with RRoute and UI changes, new route = {0}", Utils.RouteToStr(benchModelRoute));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -373,15 +364,20 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void RunDeviceAfter()
|
public void RunDeviceAfter()
|
||||||
{
|
{
|
||||||
/// Synchronize benchModelRoute with RRoute
|
///
|
||||||
if (!IsUIBlocked && bitsChangedByUI != 0)
|
/// Combine data from the current route and from UI
|
||||||
|
///
|
||||||
|
lock (this)
|
||||||
{
|
{
|
||||||
benchModelRoute = (benchModelRoute & ~bitsChangedByUI) | (displayedRoutePlusUI & bitsChangedByUI);
|
if (!IsUIBlocked && bitsChangedByUI != 0)
|
||||||
|
{
|
||||||
|
route = (route & ~bitsChangedByUI) | (displayedRoutePlusUI & bitsChangedByUI);
|
||||||
|
bitsChangedByUI = 0;
|
||||||
|
}
|
||||||
|
displayedRoute = route;
|
||||||
|
displayedRoutePlusUI = route;
|
||||||
bitsChangedByUI = 0;
|
bitsChangedByUI = 0;
|
||||||
}
|
}
|
||||||
displayedRoute = Route;
|
|
||||||
displayedRoutePlusUI = Route;
|
|
||||||
bitsChangedByUI = 0;
|
|
||||||
ProcessData.UpdateMeasuredValuesAndSetpoints();
|
ProcessData.UpdateMeasuredValuesAndSetpoints();
|
||||||
Bridge.OnStateMachineTick(this, new StateMachineTickEventArgs(displayedRoute, ProcessData.MsrmntAvailableFlags, ProcessData.MeasuredValues,
|
Bridge.OnStateMachineTick(this, new StateMachineTickEventArgs(displayedRoute, ProcessData.MsrmntAvailableFlags, ProcessData.MeasuredValues,
|
||||||
ProcessData.AltStrings, ProcessData.Setpoints));
|
ProcessData.AltStrings, ProcessData.Setpoints));
|
||||||
@@ -405,7 +401,7 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!outputsInitialized || (outputLatch & routeMask) != (benchModelRoute & routeMask)) /// || (StateMachine.Time - lastStateMachineTime) >= 15)
|
if (!outputsInitialized || (outputLatch & routeMask) != (route & routeMask)) /// || (StateMachine.Time - lastStateMachineTime) >= 15)
|
||||||
{
|
{
|
||||||
var actionsToModify = actionQueue.Where(x => (x.ActionId == ActionID.ChangeRoute));
|
var actionsToModify = actionQueue.Where(x => (x.ActionId == ActionID.ChangeRoute));
|
||||||
bool oneModified = false;
|
bool oneModified = false;
|
||||||
@@ -418,14 +414,14 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
}
|
}
|
||||||
|
|
||||||
oneModified = true;
|
oneModified = true;
|
||||||
a.Route = (ulong)benchModelRoute;
|
a.Route = (ulong)route;
|
||||||
log.InfoFormat("ChangeRoute(route={0:X}) ... an action in the queue modified", benchModelRoute);
|
log.InfoFormat("ChangeRoute(route={0:X}) ... an action in the queue modified", route);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!oneModified)
|
if (!oneModified)
|
||||||
{
|
{
|
||||||
actionQueue.Enqueue(Action.ChangeRoute(false, (ulong)benchModelRoute));
|
actionQueue.Enqueue(Action.ChangeRoute(false, (ulong)route));
|
||||||
log.InfoFormat("ChangeRoute(route={0:X}) ... a new action enqueued", (ulong)benchModelRoute);
|
log.InfoFormat("ChangeRoute(route={0:X}) ... a new action enqueued", (ulong)route);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
|
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
|
||||||
@@ -440,10 +436,16 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
{
|
{
|
||||||
outputsInitialized = true;
|
outputsInitialized = true;
|
||||||
outputLatch = combinedAction.Route;
|
outputLatch = combinedAction.Route;
|
||||||
lastStateMachineTime = StateMachine.Time;
|
if (cbCfg.DebugLevel != DebugMode.Normal)
|
||||||
|
{
|
||||||
|
Data.Vystupy = combinedAction.Route ^ valvesToInvert;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cbCfg.DebugLevel == DebugMode.Normal) serialPort.Write(outData, 0, outData.Length);
|
if (cbCfg.DebugLevel == DebugMode.Normal)
|
||||||
|
{
|
||||||
|
serialPort.Write(outData, 0, outData.Length);
|
||||||
|
}
|
||||||
|
|
||||||
string s = Telegram.LogTelegram("Sent: ", outData);
|
string s = Telegram.LogTelegram("Sent: ", outData);
|
||||||
Debug.WriteLine(s);
|
Debug.WriteLine(s);
|
||||||
@@ -506,11 +508,11 @@ namespace TBF.Rig.ControlBoard.Uni
|
|||||||
/// <returns>Bits of changed valves are set in the return value</returns>
|
/// <returns>Bits of changed valves are set in the return value</returns>
|
||||||
public UInt128 SetValves(UInt128 valvesToOpen, UInt128 valvesToClose, IList<BuiltIn.ValveEx.Valve> logicalFnValves)
|
public UInt128 SetValves(UInt128 valvesToOpen, UInt128 valvesToClose, IList<BuiltIn.ValveEx.Valve> logicalFnValves)
|
||||||
{
|
{
|
||||||
UInt128 oldRoute = benchModelRoute;
|
UInt128 oldRoute = route;
|
||||||
benchModelRoute = (benchModelRoute | valvesToOpen) & (~valvesToClose);
|
route = (route | valvesToOpen) & (~valvesToClose);
|
||||||
foreach (var logFnV in logicalFnValves) logFnV.UpdateRoute(ref benchModelRoute);
|
foreach (var logFnV in logicalFnValves) logFnV.UpdateRoute(ref route);
|
||||||
log.DebugFormat("SetValves(x,x), new route = {0}", Utils.RouteToStr(benchModelRoute));
|
log.DebugFormat("SetValves(x,x), new route = {0}", Utils.RouteToStr(route));
|
||||||
UInt128 retVal = oldRoute ^ benchModelRoute;
|
UInt128 retVal = oldRoute ^ route;
|
||||||
|
|
||||||
log.DebugFormat("{0}.SetValves({1}, {2}) returns {3}", Name, valvesToOpen.ToString("X"), valvesToClose.ToString("X"), retVal.ToString("X"));
|
log.DebugFormat("{0}.SetValves({1}, {2}) returns {3}", Name, valvesToOpen.ToString("X"), valvesToClose.ToString("X"), retVal.ToString("X"));
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|||||||
Reference in New Issue
Block a user