BeamNG / BeamNGpy

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

How to hide vehicles before shooting? #260

Open yuyuyu223 opened 3 months ago

yuyuyu223 commented 3 months ago

I want to hide the specified car when shooting with the camera. I bound the camera to the ego car and removed the remaining cars before shooting with the camera. However, the following error message will appear. How can I implement this function? Does beamng have a visible interface?

I used traffic flow and captured all participating vehicles:

beamng.traffic.spawn(max_amount=10)
time.sleep(10)
traffic_cars = beamng.get_current_vehicles()
traffic_cars.pop("ego")
for k, car in traffic_cars.items():
    car.connect(beamng)
    car.ai.set_mode('span')
    car.ai.set_speed(5.0, mode='limit')

I retrieve vehicle information through the following code, and then delete the vehicle:

def get_car_all_info(scenario, vehicle: Vehicle):
    if vehicle.vid not in scenario.transient_vehicles.keys():
        scenario.transient_vehicles[vehicle.vid] = vehicle
        # scenario.vehicles[vehicle.vid] = vehicle
    scenario.update()
    state = vehicle.state.copy()
    bbox = get_car_bbox(vehicle)
    state.update(bbox)
    return state

def get_car_bbox(vehicle: Vehicle):
    """
    Calculate the bounding box of a given vehicle.

    Parameters:
        vehicle (object): The vehicle object for which to calculate the bounding box.

    Returns:
        dict: A dictionary containing the bounding box coordinates.
    """
    bbox = vehicle.get_bbox()
    return bbox
for car in traffic_cars.values():
        state = get_car_all_info(scenario, car)
        car_states.append(state)
        beamng.vehicles.despawn(car)

Then I capture images:

  for camera in camera_ls:
      image, extra, c2w = camera_capture(camera, ego)
      image_ls.append(image)

But I received the following error message: image

BeamNG 0.31.3 BeamNGpy 1.28

aivora-beamng commented 3 months ago

Hi, there seems to be a race condition in the Lua part of the function. We will fix this in the next version, until then, you can use the following version of the getFullCameraRequest function (replace the definition in %BNG_HOME%/lua/ge/extensions/tech/sensors.lua with this one):

local function getFullCameraRequest(sensorId)
  Engine.Annotation.enable(true)
  AnnotationManager.setInstanceAnnotations(false)
  local semanticData = Research.GpuRequestManager.sendBlockingCameraGpuRequest(sensorId)
  AnnotationManager.setInstanceAnnotations(true)
  local instanceData = Research.GpuRequestManager.sendBlockingCameraGpuRequest(sensorId)
  AnnotationManager.setInstanceAnnotations(false)
  Engine.Annotation.enable(false)
  local out = {}
  out['colour'] = instanceData['colour']
  out['annotation'] = semanticData['annotation']
  out['depth'] = instanceData['depth']
  out['instance'] = instanceData['annotation']
  return out
end

Also, if you do not need both the instance and object annotation readings, you should use the Camera.poll function, the GetFullCameraRequest is much slower.


To avoid despawning the other vehicles, you can make them transparent instead. Try whether this function works for your usecase:

def set_visibility(beamng: BeamNGpy, vehicle: Vehicle, alpha: float):
    beamng.queue_lua_command(f'core_vehicle_partmgmt.setHighlightedPartsVisiblity({alpha}, scenetree.findObject("{vehicle.vid}"):getID())')

set_visibility(beamng, ego, 0.0) # make invisible
set_visibility(beamng, ego, 1.0) # make visible
yuyuyu223 commented 3 months ago

I used pop to avoid affecting the ego car:

traffic_cars.pop("ego")

But what is puzzling is that the other cars in the scene are still visible, while the ego car actually becomes invisible, I want to know what exactly happened.

for car in traffic_cars.values():
    set_visibility(beamng, car, 0.0)

image image

aivora-beamng commented 3 months ago

Sorry, there has been an error in the set_visibility function, try this version:

def set_visibility(beamng: BeamNGpy, vehicle: Vehicle, alpha: float):
    beamng.queue_lua_command(f'core_vehicle_partmgmt.setHighlightedPartsVisiblity({alpha}, scenetree.findObject("{vehicle.vid}"):getID())')

Also, you should ensure that traffic_cars = beamng.get_current_vehicles() is called after all the traffic vehicles are spawned.