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

Ensuring DReyeVR does not give ~empty VehicleControl inputs in order to run external agents #125

Merged
merged 2 commits into from
Jul 30, 2023

Conversation

shh1v
Copy link
Contributor

@shh1v shh1v commented Jul 26, 2023

When running a route scenario using scenario_runner with a specified route and agent, in every tick, the scenario_manager.py gives control input to the ego vehicle.

python scenario_runner.py --route srunner/data/route_1.xml srunner/data/no_scenarios.json --agent srunner/autoagents/npc_agent.py

In _tick_scenario of scenario_manager.py:

            if self._agent is not None:
                print(f"Ego action for {self.ego_vehicles[0]} (1 of {len(self.ego_vehicles)}): {ego_action}")
                self.ego_vehicles[0].apply_control(ego_action)

However, the current implementation in DReyeVRPawn.cpp retrieves the Logitech wheel data, and gives an empty VehicleControl object if no input from the wheel, or Logitech wheel is disconnected. The problem with this issue is that if no input is given, the implementation flushes empty vehicle controls:

In AEgoVehicle::TickVehicleInputs() of EgoInputs.cpp:

    FVehicleControl LastAppliedControl = GetVehicleControl();
    int bIncludeLast = static_cast<int>(GetAutopilotStatus());
    FVehicleControl ManualInputs;
    // only include LastAppliedControl when autopilot is running (bc it would have flushed earlier this tick)
    ManualInputs.Steer = VehicleInputs.Steering + bIncludeLast * LastAppliedControl.Steer;
    ManualInputs.Brake = VehicleInputs.Brake + bIncludeLast * LastAppliedControl.Brake;
    ManualInputs.Throttle = VehicleInputs.Throttle + bIncludeLast * LastAppliedControl.Throttle;
    ManualInputs.bReverse = bReverse;
    this->ApplyVehicleControl(ManualInputs, EVehicleInputPriority::User);
    // send these inputs to the Carla (parent) vehicle
    FlushVehicleControl();
    VehicleInputs = DReyeVR::UserInputs(); // clear inputs for this frame

Since this function is called in every tick, any other input given by a client is not considered, and thus, validation is required to check if the VehicleControl object does not have zero parameter. If so, VehicleControl must not be applied.

    // apply inputs to this vehicle only when either one of the parameter is non-zero or autopilot is on
    if ((!FMath::IsNearlyEqual(ManualInputs.Steer, 0.f, 0.02f) ||
        !FMath::IsNearlyEqual(ManualInputs.Brake, 0.f, 0.02f) ||
        !FMath::IsNearlyEqual(ManualInputs.Throttle, 0.f, 0.02f)) ||
        GetAutopilotStatus())
    {
        this->ApplyVehicleControl(ManualInputs, EVehicleInputPriority::User);
        // send these inputs to the Carla (parent) vehicle
        FlushVehicleControl();
    }

Note: FMath::IsNearlyEqual is used because even when input from Logitech steering wheel by the user is not given, it still sends very close to zero values.
Note: Initial issue I made at CARLA/scenario_sunner.

I am interested in hearing what would be the drawbacks of my approach.

@GustavoSilvera
Copy link
Collaborator

Sounds reasonable to me. This is an approach similar to what we have in DReyeVRPawn.cpp which works well enough.

@ajdroid ajdroid merged commit 0bfd613 into HARPLab:main Jul 30, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants