UUV/AUV Simulation -- No user inputs?

Hi all,

New member here, looking for some advice from any seasoned vets out there. I’ll try to bulletize where I’m at, and where I’m trying to go.

Current state:

  • I’ve created an Autonomous Underwater Vehicle (AUV) Simulator in python (using tkinter for the GUI)
  • The simulator is fully functional: I’ve built my own “physics” engine with all relevant hydrodynamics/forces/moments, a vehicle model which includes s/w logic, and thruster/actuator models
  • The simulator currently outputs results graphically using matplotlib

Desired state:

  • I’d like to use Panda3D to update the position/orientation of my AUV model in 3D, using states updated during the simulation.

Notes: I have a vehicle model and ‘world’ model that I can manipulate in a standalone script. I’ve read up on using tasks in panda to update the vehicle states, and I’ve been able to do that in my standalone script. My question is, how can I dynamically pass the output of my simulator (basically a while loop) to panda? I’d like to do it live, but would be just as happy to do the 3D simulation AFTER my simulator has finished and stored all the vehicle states as a 32Hz time series.

Any and all suggestions greatly appreciated!

Edit: I say ‘No user inputs’ because it seems Panda’s task/task manager are mostly used to handle user inputs like mouse/keyboard actions. In my case, the simulator creates a time-series of states (position / attitude) based on prescribed mission file.

Hi, welcome to the community! :slight_smile:

What exactly does the output of your simulation look like? Is it something like position and rotation angles? You should be able to set those easily on corresponding Panda nodes using scene graph manipulations like setPos at the end of your loop.

You need to make sure that your loop isn’t preventing the Panda render loop from running. You should consider putting the simulation in a task function and having Panda invoke that function with a given time period between each iteraiton using taskMgr.doMethodLater(1/32.0, yourFunction). Another approach is to run your simulation in a separate thread and pass the results of the simulation to the main thread, which would set the appropriate Panda states.

1 Like

Hi rdb,

Thanks for the quick reply. Yes, my simulator outputs position and rotations angles, among other things. You’ve pretty much nailed where I’m getting hung up. Because the program is complete and I’m adding the Panda capability as an afterthought, reorganizing everything into a Panda task seems pretty daunting. Sounds like the multi-threading option is the option for me, although I have no experience doing that. Time to read up!

One last question, for multi-threading, is this a situation where I need to be using the Panda messaging capability?

Thanks again.

All you’d really need to do to use tasks is split out the innards of the while loop into a function; once you do that, you can simply invoke it in a task. If you need to store any state, you’re probably best off putting your simulation into a separate class, with a function that you can invoke on it to update the state every frame. That is better code-organisation-wise and also keeps it separate from any decision of whether you end up invoking it in task or a while loop in a thread.

Otherwise, it actually is possible to put a while loop in a task, although it’s not often-done. This is done by putting a yield task.cont or yield task.again inside the while loop, which instructs Panda to pause that task and continue where it left off the next time the task continues (either next frame, or after a given amount of time, depending on how you set the task up).

If you choose the thread approach: Panda is thread safe in that you can update the position of nodes inside a thread, so you can decide to do that right after the simulation ends, but this may cause synchronization issues since Panda may be rendering a frame while you are updating the simulation, so some parts of the simulation may show up out-of-sync. It may be better to instead simply copy the results of the simulation into some structure and pass it off to the main thread, where you use a task to update the scene graph from the latest results from the thread.

Use of Panda messaging classes is not needed; Python’s own primitives should suffice here.

1 Like

rdb,

HUGE help! The yield doesn’t quite work how I hoped it would, but I’m now able to collect all the simulation states and THEN execute the 3D simulation. This has some advantages, the biggest that I can give the user the ability to speed up/slow down the playback since all of the states are predetermined.

You could also run your simulation in a deamon thread and write out the states to a queue, then have a panda task pop the states from the other side of the queue.
If you’re recording the states for later playback then you could use a sequence with some intervals to have free interpolation and full control over the playback speed.