Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different blocking behaviors of CSimulator::Execute #130

Open
jtrautmann opened this issue Jan 22, 2020 · 5 comments
Open

Different blocking behaviors of CSimulator::Execute #130

jtrautmann opened this issue Jan 22, 2020 · 5 comments
Assignees

Comments

@jtrautmann
Copy link

If you use the CSimulator::Execute function, it has different blocking behaviors depending on the visualization method:

Using the CDefaultVisualization, the Execute function exits when CSimulator::Terminate gets called.
Using the CQTOpenGLRender, the Execute function keeps blocking when CSimulator::Terminate get called.

This leads to the following problem for me:
I want to change the environment after a certain number of steps for reinforcement learning. With the CDefaultVisualization, I can have the following code:

# main thread
CSimulator& cSimulator = CSimulator::GetInstance();
cSimulator.SetExperimentFileName(file);
cSimulator.LoadExperiment();
while(run) {
  cSimulator.Execute();
  cSimulator.Reset();  // or SetExperimentFileName, followed by LoadExperiment
}

# second thread
CSimulator& cSimulator = CSimulator::GetInstance();
cSimulator.Terminate();

The second part gets executed when a callback is called. This causes the Execute function to exit and the environment gets changed in the main thread.
Using the CQTOpenGLRender, this won't work, as the Execute function keeps blocking after calling Terminate. But it also isn't possible to call Reset or LoadExperiment in the second thread, as this causes a segmenation fault. So I don't even see how to solve this in that case.

So, the following questions arise for me:

  1. Wouldn't it make more sense to define a general blocking behavior all CVisualization must stick to?
  2. Wouldn't it make sense that also the CQTOpenGLRender stops blocking if Terminate gets called?
  3. Is there any way how can I solve the problem with the CQTOpenGLRender?
@allsey87
Copy link
Collaborator

allsey87 commented Jan 22, 2020

While I tend to agree that this behavior is inconsistent and that such behavior should be well defined for visualizations, there just isn't enough time available to fix these sorts of issues... Not to mention that such changes may break other people's code and scripts.

If you want to use ARGoS in this way, I would suggest forking the repository and perhaps modifying CQTOpenGLMainWindow::CreateConnections to get the behavior that you want. I wouldn't assume that the Qt subsystem is going to play along with what you are trying to do, you might want to check the docs for Qt.

@ilpincy
Copy link
Owner

ilpincy commented Jan 22, 2020

I'm not sure I understand what you mean by 'blocking' in this request. Can you please elaborate?

@ilpincy ilpincy self-assigned this Jan 22, 2020
@jtrautmann
Copy link
Author

@allsey87 Ok I can understand that there isn't enough time available. Unfortunately, I have the same problem. But I found a solution for my specific problem, where I only call Execute once if I'm using CQTOpenGLRender.

@ilpincy Using CDefaultVisualization, if I call Terminate, the call of Execute ends and I get to the line from above that says

cSimulator.Reset();

Using CQTOpenGLRender, this doesn't happen because the window doesn't get called and so you stay in the line from above that says

cSimulator.Execute();

even if Terminategot called. The call of Execute only ends when the window is closed.

I hope this was more clear?

@ilpincy
Copy link
Owner

ilpincy commented Jan 24, 2020

I'm not sure I would call this an inconsistency. If I understand correctly, you would like to be able to call CSimulator::Terminate() from a different thread with respect to the one you launch ARGoS from, and you also want to CSimulator::Terminate() to close the window and allow CSimulator::Reset() to be called. I did not design ARGoS to work this way, so what you're trying to do is not technically correct.

The main loop in CSimulator::Execute() is managed by the visualization. If you want ARGoS to run with a graphical visualization, most graphics libraries (Qt included) need to own the main loop to be able to manage events. This means that the lifetime of CSimulator::Execute() must match the lifetime of the GUI.

The fact that the default visualization (a simple while loop) allows you to run the code you propose is just a mere consequence of that visualization being so simple. It's true your code works for it, but it's a hack - something that should not be done if you want your code to work as intended. If I needed to make things consistent, I would change the default visualization to prevent the code you're writing, not the other way around.

The correct way to achieve what you need is to use the loop functions and the Qt user functions. Use CLoopFunctions::IsExperimentFinished() to define custom logic to end an experiment, and extend the class CQTUserFunctions to simulate pressing the Reset button. A possible way to make this last part simpler for you could be to add the method CQTUserFunctions::Reset(), which could be useful more in general.

@jtrautmann
Copy link
Author

@ilpincy Yes, you understand it correctly. Thank you, that responds my question. In my opinion, in this case it really would be better to change the behavior of the default visualization or at least add an information in the documentation about this behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants