question

Tuan avatar image
0 Likes"
Tuan asked Jeanette F commented

Flexscript for sending the message via socket repeatedly

My flexsim version is 2020

The flexsim file is server

The python file is client


problem.fsm

socket-TCP客戶端.py


At the beginning, the message is sent from the client to the server , and then the server applies the message to the experimenter .

The result is sent to the client , after the experimenter ends .

My purpose is I want the process to be repeated until the result sent from the server is what the client wants

I write a loop.

When the code ends the first loop, it runs the next loop, but loop didn't work.

I think the problem is the need to wait for the result to be send to the client before starting the next loop.

Maybe I can add a trigger(On serversend trigger) via flexscript How to do?

How to modify the flexscript that waits until the server send the result to the client ??

擷取.png


FlexSim 20.0.10
flexscriptsocket
擷取.png (17.2 KiB)
problem.fsm (92.1 KiB)
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Kavika F avatar image
1 Like"
Kavika F answered Jeanette F commented

Hey @Tuan, I think there's an issue with the loop because there isn't enough time for the experimenter to wait before the "serverreceive" command blocks FlexSim until it receives a response. However, you can't respond because you haven't received the results from the Experimenter; thus, it's caught in this deadlock state. Reference Phil's answer above for a good explanation of how script execution works in FlexSim.

· 13
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Tuan avatar image Tuan commented ·

@Kavika F

For the 2020 version

Is there a solution?

0 Likes 0 ·
Tuan avatar image Tuan Tuan commented ·

@Kavika F

Line 17 executes successfully

Why can't lines 18 and 19 be executed?

0 Likes 0 ·
Kavika F avatar image Kavika F ♦ Tuan commented ·

Hey @Tuan, I got it to work with some help from the links that Phil posted above. Here's what I've got. The working files are below. Make sure to run your model's script first and then your python code.


I started by making some User Commands to simplify how the code looks:

// getInput()
return serverreceive(Model.find("Tools/client").value, NULL, 15, 0);
 
// runExperimenter(string input)
string input = param(1);
Model.find("Tools/Experimenter/ExperimentVariables/Inter arrival time/Scenario 1").value = input;
applicationcommand("runexperiment");

In a single script window I used your code (modified slightly for exiting):

endSocket();
startSocket(8888);

string input = getInput();
if (input.toLowerCase() == "exit") {
  return -1;
}
runExperimenter(input);

Once the script ran, it blocked waiting for a connection from the python code. After sending your input, it would run an experiment. When completed, it would run the EndOfExperiment code, which performed the "seversend" function you had before. Instead of running the next blocking input and experimenter inside of the EndOfExperiment trigger, I ran it using a postwindowmessage.

serversend(server, message);
postwindowmessage(systemwindow(8), FLEXSIM_MESSAGE_USER_NODEFUNCTION, Model.find("Tools/test"), 1234);

With these parameters, it ran the Flexscript Node I added called "test" found in the Tools in the tree.

1667335630944.png

That is where I put the getInput and runExperimenter code.

string input = getInput();
if (input == "") {
  return 0;
}
//print("Input:", input);
runExperimenter(input);
return 1;

I'm not sure why it wasn't working before, but the postwindowmessage code seems to fix it.

problem_5.fsm

socket-tcp___.py

0 Likes 0 ·
problem-5.fsm (31.4 KiB)
socket-tcp.py (1002 B)
1667335652728.png (25.2 KiB)
Show more comments
Phil BoBo avatar image
1 Like"
Phil BoBo answered Phil BoBo edited

When FlexSim is executing your script, FlexSim runs the code one line at a time. Within your script, you call a command to tell FlexSim to then execute a bunch of other processing (running the experiment). Your script needs to finish before FlexSim can do that other processing. FlexSim is busy running your script and can't execute other code until your script is done. Calling applicationcommand("runexperiment") gets the experiment started, but you have to let your script finish in order for it to be able to process the experiment.

Instead of a synchronous loop in a single FlexScript script that is processed by the FlexSim application, your loop should be external to FlexSim's processing.

See:

Automatically Configure and Run a FlexSim Model

Using FlexSim with Python/C api

Future Python and FlexSim integration

Launch FlexSim from Python

Reinforcement Learning Using Previous Versions

From an external control loop outside of FlexSim in whatever programming language you want, you should spawn an instance of FlexSim and then have your 1 -> 1000 for() loop there that communicates with the instance of FlexSim to run the experiments. Your loop should not be within FlexSim.

Within FlexSim, it should receive the message to start the experiment and run it. When the experiment ends, you should then receive another message to return the results and determine whether to start another experiment run with different inputs. This logic should not be all within the same function. You should have one function that starts the processing when you spawn an instance of FlexSim (On Model Open) and another function later when the processing ends (On Experiment End).

While the examples above are primarily focused on reinforcement learning with Python, if you understand the concepts of how the communication is happening in those examples, then you can apply them to what you are trying to accomplish regardless of external programming language or overall goal (running many experiments vs. training an AI).

These concepts also apply regardless of the version of FlexSim. You can do this with any version of FlexSim. Newer versions of FlexSim may have code that follows these concepts to make certain things easier and faster for the user, but the underlying concepts will work with any versions of FlexSim.

For examples:

The 22.1 Python Connector makes it easier to control FlexSim from Python. The 22.1 Range-based Experimenter Jobs make specifying a range of inputs for a design-of-experiment easier. The 22.0 Reinforcement Learning tool makes training AIs require less code on the FlexSim side. Etc.

· 1
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Tuan avatar image Tuan commented ·

1667203354202.png

@Phil BoBo Why can't this be successful? thanks!

0 Likes 0 ·
1667203354202.png (191.3 KiB)