How to read a FSM diagram - network-programming

How do i take this diagram and translate it into a useable program. I'm not really sure how to read this diagram. If someone could just kind of walk me through, maybe show an example of code and how it relates to the diagram, that be great.
Thanks!

Circles with text inside are the states. Text describes what the state is.
Dashed arrow points to starting state.
Outgoing arrows determine where this state could change. Beside of the arrow is the text divided by the line into upper part and lower part. Lower part is actions that should take place when arrow transition is executed. Upper part is conditions. When they are true - this transition is executed (and so lower part).
Lambda symbol means you should do nothing except changing current state when transition takes place.
So lower parts have coarse corresponding to your functions. And upper parts are the points where you should wait for conditions - polling or async waiting for pending I/O packets, whatever.
Here is some pseudo-code similar to C (I've written it just here so do not assume it works or even compiles):
enum State { WaitFor0Call, WaitForAck0, WaitForCall1, WaitForAck1 }
int main() {
State state = WaitFor0Call;
while (1) {
switch (state) {
case WaitFor0Call:
if (rdt_rcv(rcvpkt)) continue;
if (rdt_send(data)) {
state = WaitForAck0;
sndpkt = make_pkt(0, data, checksum);
udt_send(sndpkt);
start_timer();
}
break;
case WaitForAck0:
// ...similar code...
break;
case WaitForCall1:
// ...similar code...
break;
case WaitForAck1:
// ...similar code...
break;
}
}
}
You should also take into account that receive and send functions could be blocking, so code if (rdt_rcv(rcvpkt)) whatever; is technically incorrect as you don't check for rdt_send until it returns control. So FSM communicates only logical flow, not technical aspects of how it should be organized, thread management etc. And my code doesn't show this aspects also because it could be decently complicated depending on your needs and because you didn't give enough details to make informed advices on these sort of things :)
My only guess is that you would have some sort of bi-directed stream (for input and output respectively) and conditions would be like if (there_is_ready_for_consuming_packet_in_the_input_queue) continue; and if (data_was_put_to_outgoing_stream_successfully) ...;

Related

Handling TCP Data Without a large switch statement

I am working on an app that will send and receive data with a TCP socket in IOS using Swift.
I have the communication working fine but what I am trying to do is think of a way to handle the incoming data without a large switch statement.
The app could be sending out various requests at any time but I can't guarantee in what order I will get responses. The first part of each response contains a hex address that tells what information I am receiving is.
I need to take the incoming data and perform a different calculation on it depending on what it is. What I do right now is read the hex address as it comes in and then send it to a giant switch statement which then calles the proper function to convert the data.
I am trying to come up with something better than the giant switch statement. Although I cannot count on exactly what data I will receive in any given message I do know all the possible items that could be received.
Any suggestions that any one has would be appreciated I am not used to handling data like this.
A giant switch statement is very traditional here. Just make sure to separate your work from your switch. For example, avoid this:
switch byte {
case 0x01:
doing()
various()
things()
case 0x02:
doing()
other()
things()
...
}
That code can get pretty messy, though I admit I make this mistake all the time.... The better approach is to pull out the operations:
switch byte {
case 0x01: handleOperationA()
case 0x02: handleOperationB()
...
}
func handleOperationA() { ... }
func handleOperationB() { ... }
You of course can make a constants here for 0x01, 0x02, etc., but if this is the only place these values, then creating the constant can become duplicative. The name of the function provides just as much documentation as the name of the constant. There are trade-offs here.
Another possibility is to replace your switch with a Dictionary, mapping the value to a function (or if it's exactly one byte, and most of the values are used, an Array can even work here, but that's kind of rare).
Dictionaries are nice if things are variable, or if there are a very large number of possible values, but it's not always obvious which is more efficient (the optimizer can do a lot with a switch statement of integers; don't assume dictionary lookups are always faster).
But if you're writing a networking stack, or any kind of parser, embrace a large switch statement. They're completely normal. Just keep it simple.

Events changing visual geometries

I'm trying to visualize collisions and different events visually, and am searching for the best way to update color or visual element properties after registration with RegisterVisualGeometry.
I've found the GeometryInstance class, which seems like a promising point for changing mutable illustration properties, but have yet to find and example where an instance is called from the plant (from a GeometryId from something like GetVisualGeometriesForBody?) and its properties are changed.
As a basic example, I want to change the color of a box's visual geometry when two seconds have passed. I register the geometry pre-finalize with
// box : Body added to plant
// X_WA : Identity transform
// FLAGS_box_l : box side length
geometry::GeometryId box_visual_id = plant.RegisterVisualGeometry(
box, X_WA,
geometry::Box(FLAGS_box_l, FLAGS_box_l, FLAGS_box_l),
"BoxVisualGeometry",
Eigen::Vector4d(0.7, 0.5, 0, 1));
Then, I have a while loop to create a timed event at two seconds where I would like for the box to change it's color.
double current_time = 0.0;
const double time_delta = 0.008;
bool changed(false);
while( current_time < FLAGS_duration ){
if (current_time > 2.0 && !changed) {
std::cout << "Change color for id " << box_visual_id.get_value() << "\n";
// Change color of box using its GeometryId
changed = true;
}
simulator.StepTo(current_time + time_delta);
current_time = simulator_context.get_time();
}
Eventually I'd like to call something like this with a more specific trigger like proximity to another object, or velocity, but for now I'm not sure how I would register a simple visual geometry change.
Thanks for the details. This is sufficient for me to provide a meaningful answer of the current state of affairs as well as the future (both near- and far-term plans).
Taking your question as a representative example, changing a visual geometry's color can mean one of two things:
The color of the object changes in an "attached" visualizer (drake_visualizer being the prime example).
The color of the object changes in a simulated rgb camera (what is currently dev::RgbdCamera, but imminently RgbdSensor).
Depending on what other properties you might want to change mid simulation, there might be additional subtleties/nuances. But using the springboard above, here are the details:
A. Up until recently (drake PR 11796), changing properties after registration wasn't possible at all.
B. PR 11796 was the first step in enabling that. However, it only enables it for changing ProximityProperties. (ProximityProperties are associated with the role geometry plays in proximity queries -- contact, signed distance, etc.)
C. Changing PerceptionProperties is a TODO in that PR and will follow in the next few months (single digit unless a more pressing need arises to bump it up in priority). (PerceptionProperties are associated with the properties geometry has in simulated sensors -- how they appear, etc.)
D. Changing IllustrationProperties is not supported and it is not clear what the best/right way to do so may be. (IllustrationProperties are what get fed to an external visualizer like drake_visualizer.) This is the trickiest, due to the way the LCM communication is currently articulated.
So, when we compare possible implications of changing an object's color (1 or 2, above) with the state of the art and near-term art (C & D, above), we draw the following conclusions:
In the near future, you should be able to change it in a synthesized RGB image.
No real plan for changing it in an external visualizer.
(Sorry, it seems the answer is more along the lines of "oops...you can't do that".)

iFractals MLQ5 usage not understood

Here is the code that I thought and tried. I thought that it was the right way to buy and sell for the Fractals signals. But getting buy and sell signals simultaneously.
double UP[],DOWN[];
double fractal_output = iFractals(_Symbol,_Period);
ArraySetAsSeries(UP,true);
ArraySetAsSeries(DOWN,true);
CopyBuffer(fractal_output,0,0,5,UP);
CopyBuffer(fractal_output,1,0,5,DOWN);
if (UP[1])
{
Comment("BUY");
trade.Buy(0.1);
}
if (DOWN[1])
{
Comment("SELL");
trade.Sell(0.1);
}
I don't understand how I can plan to buy and sell using the iFractals function indicator in my MQL5. What improvements need to be done?
A double fractal_output should be int not double and initialized in the OnInit(){...} just once, not each tick.
Make sure you understand which fractal is obtained when accessing UP[1] - it seems to be 0,1,2,3,4 (left to right), so you are asking for fractal 3 bars before the current Bar.
Alternatively you can get a value before the current Bar (most probably it is zero until next bar after current starts).
Make sure that you have copied the buffer correctly (it is possible that it is not copied and UP[1] may throw out-of-range error - for that reason CopyBuffer returns a number of elements actually copied (so if CopyBuffer()!=5){print();return;})
What do you expect to see when calling if(UP[1]){} ?
A buffer might take both positive values and EMPTY_VALUE (== 2^31-1).
It is better to check the value of the buffer: if(UP[i]>0){} or if(UP[i]!=EMPTY_VALUE){...}
Do not forget about a special case, when some candle has both an upper and a lower fractal - What to do in that corner-case?
It will open a Long and then open a Short (so it may close the Buy by opening a Short).
Probably you need check the open orders before that or open bar - otherwise you'll have many positions opened during one candle.
Tester will help you find other problems that you could miss when planning the EA.

Different programming styles for motion PLC

For a motionPLC project written in ST, I use a lot of stepper structured functions like this:
stepNum := 1;
CASE stepNum OF
1: (* Move axis to upper positon *)
axis.in.position := 0;
axis.start := true;
IF(axis.out.position = 0) THEN
stepNum := 2;
END_IF
2: (* Do something else *)
The goal behind this approach is to be able to wait for the drive to complete its task, before moving to the next task.
This works, but as programs grow more complex, and steps don't always need to be sequential (you can go from waiting state, to operating state, to fault state and back to waiting state), the code starts to look more like spaghetti code as written in the days of qBASIC.
Are there other styles to write this program that enable me to wait for the drive to finish its task, but that don't get so convoluted?
Please let me know if this question is 'too broad', I didn't know where else to ask.
Honestly the case statement is the best way I have found to accomplish what you are talking about. However you can combine functionality in a function or function block to reduce the amount of code written in each step... or perhaps have mini case statements within function blocks to reduce the amount of code in one place to make it more "readable".
I agree with mrsargent and the case statement constitutes a good way to implement a state machine in a program which is cyclically running.
I would suggest also using enumerations instead of numerical values for your states. In the example below, motorState is a variable of enumeration type and it makes the code much easier to read compared to having numerical values.
CASE motorState OF
MOTOR_DISABLED:
//do something here
MOTOR_READY:
//do something here
MOTOR_RUNNING:
//do something here
END_CASE

Best way to access/store persistent data in CUDA along multiple kernel calls [duplicate]

I have 2 very similar kernel functions, in the sense that the code is nearly the same, but with a slight difference. Currently I have 2 options:
Write 2 different methods (but very similar ones)
Write a single kernel and put the code blocks that differ in an if/else statement
How much will an if statement affect my algorithm performance?
I know that there is no branching, since all threads in all blocks will enter either the if, or the else.
So will a single if statement decrease my performance if the kernel function is called a lot of times?
You have a third alternative, which is to use C++ templating and make the variable which is used in the if/switch statement a template parameter. Instantiate each version of the kernel you need, and then you have multiple kernels doing different things with no branch divergence or conditional evaluation to worry about, because the compiler will optimize away the dead code and the branching with it.
Perhaps something like this:
template<int action>
__global__ void kernel()
{
switch(action) {
case 1:
// First code
break;
case 2:
// Second code
break;
}
}
template void kernel<1>();
template void kernel<2>();
It will slightly decrease your performance, especially if it's in an inner loop, since you're wasting an instruction issue slot every so often, but it's not nearly as much as if a warp were divergent.
If it's a big deal, it may be worth moving the condition outside the loop, however. If the warp is truly divergent, though, think about how to remove the branching: e.g., instead of
if (i>0) {
x = 3;
} else {
x = y;
}
try
x = ((i>0)*3) | ((i<3)*y);

Resources