BeamNG / BeamNGpy

Python API for BeamNG.tech
https://beamng.tech
MIT License
263 stars 46 forks source link

Running Multiple BeamNG Instances on the same computer #146

Closed hildebrandt-carl closed 2 years ago

hildebrandt-carl commented 3 years ago

Hi I am currently using BeamNGpy 1.17.0 with BeamNGtech 1.7.0.1.

I was wondering if it possible to run two different instances of BeamNG at the same time. I wrote a script that uses BeamNG's chase function to drive a vehicle down the road, while also spawning a random amount of traffic vehicles. When you launch BeamNGpy one of the parameters is port which I pass in on the command line argument.

However if I try and run two different instances of BeamNG using: Terminal 1:

python .\run_multi.py --port_number 30000 --number_traffic_vehicles 3

Terminal 2:

python .\run_multi.py --port_number 40000 --number_traffic_vehicles 4

Generally one of the simulations crash. I have it that sometimes it works and both simulations are able to run at the same time. I think I have two ideas as to why this could be happening. First when I launch the code I notice that regardless of the port number there is always a INFO line that says:

...
2021-08-31 14:44:44,779 INFO     Started BeamNGpy server on localhost:30000
2021-08-31 14:44:44,779 DEBUG    Starting BeamNG process...
2021-08-31 14:44:52,393 DEBUG    Connection established. Awaiting "hello"...
2021-08-31 14:44:52,394 INFO     Started BeamNGpy communicating on ('127.0.0.1', 57022)
2021-08-31 14:45:08,255 DEBUG    Starting vehicle server for V:ego_vehicle on: localhost:30001
...

You will notice that it starts communication on port 57022 this number changes each run and I cant seem to figure out where it comes from.

Then other times, I get an error shown below:

2021-08-31 14:18:20,673 WARNING  sys:1: ResourceWarning: unclosed <socket.socket fd=1464, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 30000), raddr=('127.0.0.1', 59211)>

Interestingly you can again see this raddr that I am not sure where its coming from. I have attached my code below so that this can be easily replicated.

My question is: Is it possible to run two instances of BeamNG at the same time? If so how do I set it such that BeamNG's response ports do not clash?

run_multi.zip

alessiogambi commented 3 years ago

Hi, I am afraid you need to also tell each instance to use a different user folder otherwise one will corrupt the other cache. When you create a BeamNGpy object there's a parameter called user

hildebrandt-carl commented 3 years ago

Thanks for the suggestion. I will look into it and if I can get it working write a detailed explanation so others can replicate it :)

alessiogambi commented 3 years ago

BTW, Maybe it does not fit your needs, but with the latest versions of BeamNG.tech you can also attach multiple processes/clients to the same BeamNG simulation. Last year I gave a tutorial on using BeamNG and this was one example. You can find the code and video here:

https://github.com/se2p/sbst-2021-tutorial

Of course, feel free to contribute to it with new/more examples ;)

hildebrandt-carl commented 3 years ago

Awesome thank you! I will definitely take a look and contribute where I can :)

PS this very besides the point but you are actually the reason I started with BeamNG! I started looking into it after talking to you at ICSE 2019 so thanks for that, and thanks again for pointing me in the right direction here :)

alessiogambi commented 3 years ago

Eh eh eh. Great!

Since you are familiar with BeamNG and the problems of testing-in-the-loop, I hope you'll consider participating in the 2nd SBST Tool Competition based on BeamNG: https://sbst22.github.io/tools/

We are looking for test generators but also test subjects (e.g., trajectory planners, driving agents) are welcome!

hildebrandt-carl commented 2 years ago

Just wanted to wrap this issue up. Thanks @alessiogambi for pointing me in the right direction. I was still using an older version of BeamNG that did not allow the specification of a user workspace. For anyone else who runs into this issue, here is how to solve it:

Note: While I was writing this up, I noticed this example. I haven't looked at it. But it seems to be doing exactly what I spend the last little bit figuring out.

My solution: I was running the following versions BeamNG version: BeamNG.tech.v0.23.5.1 BeamNGpy version: 1.21.1

Once you have installed everything you need to create two user workspaces. You can do that you need to follow this part of the readme. However basically what you need to do is: 1) Create an environment variable called BNG_HOME. You can do that by: Edit the system environment variables -> Environment Variables -> System Variables (NEW) 
 Varibale Name: BNG_HOME Variable Value: C:\\BeamNG.tech.v0.23.5.1

2) Create both workspaces by: Restarting the terminal (if you have just created the environment variable) and run:

# Workspace 1
mkdir C:\<insert path here>\BeamNGWorkspace
cd C:\<insert path here>\
beamngpy setup-workspace .\BeamNGWorkspace\
# Workspace 2
mkdir C:\<insert path here>\BeamNGWorkspace2
cd C:\<insert path here>\
beamngpy setup-workspace .\BeamNGWorkspace2\

You are now all good to go. All you now need to do is update the port and the user parameters when calling BeamNGpy. Here is an updated example from the readme (which I called basic_drive.py):

import argparse

from beamngpy import BeamNGpy, Scenario, Vehicle

# Get the user defined arguments
parser = argparse.ArgumentParser()
parser.add_argument('--port', type=int, default=64256, help="The port used to connect.")
parser.add_argument('--workspace', type=str, default="BeamNGWorkspace", help="The name of the workspace folder")
args = parser.parse_args()

# Get BeamNG's location and workspace
bng_loc = 'C:\\Users\\carl\\Documents\\Beamng\\BeamNG.tech.v0.23.5.1'
bng_usr = 'C:\\Users\\carl\\Documents\\Beamng\\' + args.workspace

# Launch BeamNG
bng = BeamNGpy('localhost', args.port, home=bng_loc, user=bng_usr)
bng.open()

# Create a scenario in west_coast_usa called 'example'
scenario = Scenario('west_coast_usa', 'example')

# Create an ETK800 with the license plate 'PYTHON'
vehicle = Vehicle('ego_vehicle', model='etk800', licence='PYTHON')

# Add it to our scenario at this position and rotation
scenario.add_vehicle(vehicle, pos=(-717, 101, 118), rot=None, rot_quat=(0, 0, 0.3826834, 0.9238795))

# Place files defining our scenario for the simulator to read
scenario.make(bng)

# Load and start our scenario
bng.load_scenario(scenario)
bng.start_scenario()

# Make the vehicle's AI span the map
vehicle.ai_set_mode('span')
input('Hit enter when done...')

To run multiple copies all you need to do is simply open two terminals and run: Terminal 1

python .\basic_drive.py --port 64256 --workspace BeamNGWorkspace

Terminal 2

python .\basic_drive.py --port 64257 --workspace BeamNGWorkspace2

You should then have two simulators up and running as seen below: twosimulators