I've been writing some embedded libraries for an ongoing personal project and downshifted to really think about my approach.
Particularly, I'm sanity-checking whether an object-oriented implementation for some of this stuff is even a starter, or if my OO approach is worthless.
Here's where I'm coming from.
What could be done in the class is:
What this demands of the calling code are branching if/else that can impact performance (each method call also evaluates ownership), readability, and possibly put the responsibility of determining the CS object state to the caller itself:
Then there's the idea of mapping external inputs to the state of some public bool members. Those members are evaluated at the end of the controller loop to determine the owner of the motor.
No branching required and the object manages itself from the state of inputs (Inp_Local always supercedes Inp_Disable in priority).
What do you think?
Particularly, I'm sanity-checking whether an object-oriented implementation for some of this stuff is even a starter, or if my OO approach is worthless.
Here's where I'm coming from.
- I've got a ControlStrategy (CS) class that provides the means for Device objects to self-arbitrate how they're operated.
- actuated devices contain an instance of CS.
- a device could be switched from Program (automatic) control to Operator (manual via HMI, phone app, etc.) for example.
- a device could also be switch from anything to "Local" control, meaning the physical device is responding to its own hardwired inputs (typically a drive).
- this would be handled by simply feeding the status of a local control station's Hand/Off/Auto switch to the CS.
- implementing how this is handled is the challenge, I think.
What could be done in the class is:
C++:
class CS
{
public:
void setDisabled();
void setEnabled();
void setLocal();
void releaseLocal();
int32_t getOwner(); // returns current device owner
private:
int32_t owner; // enumerated, 0: undefined, 1: Local, 2: Disabled, 8: Program, 10: Operator, ...
};
What this demands of the calling code are branching if/else that can impact performance (each method call also evaluates ownership), readability, and possibly put the responsibility of determining the CS object state to the caller itself:
C++:
void loop()
{
dvcMotor Device;
bool swAuto = getDigIn01(); // pretend these calls represent input points
bool swHand = getDigIn02();
if (!(swAuto || swHand)) // HOA switch in 'Off'
Device.CS.setDisabled();
else if (swAuto)
Device.CS.setProgram();
else if (swHand)
Device.CS.setLocal();
// or maybe:
if (!swAuto && !swHand) // HOA switch in 'Off'
Device.CS.setDisabled();
else
Device.CS.setEnabled();
if (swHand) // HOA switch in 'Hand/Local'
Device.CS.setLocal();
else
Device.CS.releaseLocal(); // ... to what? Operator? Program?
}
Then there's the idea of mapping external inputs to the state of some public bool members. Those members are evaluated at the end of the controller loop to determine the owner of the motor.
C++:
class CS
{
public:
bool Inp_Disable;
bool Inp_Local;
void update(); // synchronous program call to 'refresh' object state
int32_t getOwner(); // returns current device owner
private:
int32_t owner; // enumerated, 0: undefined, 1: Local, 2: Disabled, 8: Program, 10: Operator, ...
};
C++:
void loop()
{
dvcMotor Device;
Device.CS.Inp_Disable = getDigIn01();
Device.CS.Inp_Local = getDigIn02();
// possibly a bunch of process-related code
Device.CS.update();
}
No branching required and the object manages itself from the state of inputs (Inp_Local always supercedes Inp_Disable in priority).
What do you think?
Last edited: