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

External physics engine #3626

Merged
merged 5 commits into from
Apr 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions AirLib/include/physics/DebugPhysicsBody.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,16 @@ class DebugPhysicsBody : public PhysicsBody {
std::cout << " ------------------------------------------------" << std::endl;
}

virtual void updateKinematics() override
{
PhysicsBody::updateKinematics();
}

virtual real_T getRestitution() const override
{
return restitution_;
}

virtual real_T getFriction() const override
{
return friction_;
Expand Down
59 changes: 59 additions & 0 deletions AirLib/include/physics/ExternalPhysicsEngine.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#ifndef airsim_core_ExternalPhysicsEngine_hpp
#define airsim_core_ExternalPhysicsEngine_hpp

#include "common/Common.hpp"
#include "physics/PhysicsEngineBase.hpp"
#include <iostream>
#include <sstream>
#include <fstream>
#include <memory>
#include "common/CommonStructs.hpp"
#include "common/SteppableClock.hpp"
#include <cinttypes>

namespace msr
{
namespace airlib
{

class ExternalPhysicsEngine : public PhysicsEngineBase {
public:
ExternalPhysicsEngine()
{
}

//*** Start: UpdatableState implementation ***//
virtual void resetImplementation() override
{

}

virtual void update() override
{
PhysicsEngineBase::update();

for (PhysicsBody* body_ptr : *this) {
body_ptr->updateKinematics();
body_ptr->update();
}

}
virtual void reportState(StateReporter& reporter) override
{
for (PhysicsBody* body_ptr : *this) {
reporter.writeValue("ExternalPhysicsEngine",true);
reporter.writeValue("Is Grounded", body_ptr->isGrounded());
}
//call base
UpdatableObject::reportState(reporter);
}
//*** End: UpdatableState implementation ***//

};

} //namespace
} //namespace
#endif
7 changes: 7 additions & 0 deletions AirLib/include/physics/PhysicsBody.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ class PhysicsBody : public UpdatableObject {
kinematics_->setState(state);
kinematics_->update();
}
/**
* Update kinematics without a state
*/
virtual void updateKinematics()
{
kinematics_->update();
}


public: //methods
Expand Down
15 changes: 14 additions & 1 deletion AirLib/include/vehicles/multirotor/MultiRotorPhysicsBody.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,24 @@ class MultiRotorPhysicsBody : public PhysicsBody {
//*** End: UpdatableState implementation ***//


//Physics engine calls this method to set next kinematics
//Fast Physics engine calls this method to set next kinematics
virtual void updateKinematics(const Kinematics::State& kinematics) override
{
PhysicsBody::updateKinematics(kinematics);

updateSensorsAndController();
}

//External Physics engine calls this method to keep physics bodies updated and move rotors
virtual void updateKinematics() override
{
PhysicsBody::updateKinematics();

updateSensorsAndController();
}

void updateSensorsAndController()
{
updateSensors(*params_, getKinematics(), getEnvironment());

//update controller which will update actuator control signal
Expand Down
34 changes: 34 additions & 0 deletions PythonClient/multirotor/external_physics_engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import setup_path
import airsim
import time

# This example shows how to use the External Physics Engine
# It allows you to control the drone through setVehiclePose and obtain collision information.
# It is especially useful for injecting your own flight dynamics model to the AirSim drone.

# Use Blocks environment to see the drone colliding and seeing the collision information
# in the command prompt.

# Add this line to your settings.json before running AirSim:
# "PhysicsEngineName":"ExternalPhysicsEngine"


client = airsim.VehicleClient()
client.confirmConnection()
pose = client.simGetVehiclePose()

pose.orientation = airsim.to_quaternion(0.1, 0.1, 0.1)
client.simSetVehiclePose( pose, False )

for i in range(900):
print(i)
pose = client.simGetVehiclePose()
pose.position = pose.position + airsim.Vector3r(0.03, 0, 0)
pose.orientation = pose.orientation + airsim.to_quaternion(0.1, 0.1, 0.1)
client.simSetVehiclePose( pose, False )
time.sleep(0.003)
collision = client.simGetCollisionInfo()
if collision.has_collided:
print(collision)

client.reset()
5 changes: 5 additions & 0 deletions Unreal/Plugins/AirSim/Source/SimMode/SimModeWorldBase.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "SimModeWorldBase.h"
#include "physics/FastPhysicsEngine.hpp"
#include "physics/ExternalPhysicsEngine.hpp"
#include <exception>
#include "AirBlueprintLib.h"

Expand Down Expand Up @@ -71,6 +73,9 @@ std::unique_ptr<ASimModeWorldBase::PhysicsEngineBase> ASimModeWorldBase::createP

physics_engine->setWind(getSettings().wind);
}
else if (physics_engine_name == "ExternalPhysicsEngine") {
physics_engine.reset(new msr::airlib::ExternalPhysicsEngine());
}
else {
physics_engine.reset();
UAirBlueprintLib::LogMessageString("Unrecognized physics engine name: ", physics_engine_name, LogDebugLevel::Failure);
Expand Down
2 changes: 1 addition & 1 deletion Unreal/Plugins/AirSim/Source/SimMode/SimModeWorldBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <memory>
#include <vector>
#include "api/VehicleSimApiBase.hpp"
#include "physics/FastPhysicsEngine.hpp"
#include "physics/PhysicsEngineBase.hpp"
#include "physics/World.hpp"
#include "physics/PhysicsWorld.hpp"
#include "common/StateReporterWrapper.hpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "common/ClockFactory.hpp"
#include <memory>
#include "vehicles/multirotor/api/MultirotorRpcLibServer.hpp"
#include "common/SteppableClock.hpp"


void ASimModeWorldMultiRotor::BeginPlay()
Expand Down Expand Up @@ -137,4 +138,4 @@ msr::airlib::VehicleApiBase* ASimModeWorldMultiRotor::getVehicleApi(const PawnSi
{
const auto multirotor_sim_api = static_cast<const MultirotorPawnSimApi*>(sim_api);
return multirotor_sim_api->getVehicleApi();
}
}
2 changes: 1 addition & 1 deletion docs/image_apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ Before AirSim v1.2, cameras were accessed using ID numbers instead of names. For

## "Computer Vision" Mode

You can use AirSim in so-called "Computer Vision" mode. In this mode, physics engine is disabled and there is no vehicle, just cameras. You can move around using keyboard (use F1 to see help on keys). You can press Record button to continuously generate images. Or you can call APIs to move cameras around and take images.
You can use AirSim in so-called "Computer Vision" mode. In this mode, physics engine is disabled and there is no vehicle, just cameras (If you want to have the vehicle but without its kinematics, you can use the Multirotor mode with the Physics Engine [ExternalPhysicsEngine](settings.md##physicsenginename)). You can move around using keyboard (use F1 to see help on keys). You can press Record button to continuously generate images. Or you can call APIs to move cameras around and take images.

To active this mode, edit [settings.json](settings.md) that you can find in your `Documents\AirSim` folder (or `~/Documents/AirSim` on Linux) and make sure following values exist at root level:

Expand Down
2 changes: 1 addition & 1 deletion docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ To turn off the engine sound use [setting](settings.md) `"EngineSound": false`.
This allows you to specify your own vehicle pawn blueprints, for example, you can replace the default car in AirSim with your own car. Your vehicle BP can reside in Content folder of your own Unreal project (i.e. outside of AirSim plugin folder). For example, if you have a car BP located in file `Content\MyCar\MySedanBP.uasset` in your project then you can set `"DefaultCar": {"PawnBP":"Class'/Game/MyCar/MySedanBP.MySedanBP_C'"}`. The `XYZ.XYZ_C` is a special notation required to specify class for BP `XYZ`. Please note that your BP must be derived from CarPawn class. By default this is not the case but you can re-parent the BP using the "Class Settings" button in toolbar in UE editor after you open the BP and then choosing "Car Pawn" for Parent Class settings in Class Options. It is also a good idea to disable "Auto Possess Player" and "Auto Possess AI" as well as set AI Controller Class to None in BP details. Please make sure your asset is included for cooking in packaging options if you are creating binary.

### PhysicsEngineName
For cars, we support only PhysX for now (regardless of value in this setting). For multirotors, we support `"FastPhysicsEngine"` only.
For cars, we support only PhysX for now (regardless of value in this setting). For multirotors, we support `"FastPhysicsEngine"` and `"ExternalPhysicsEngine"`. `"ExternalPhysicsEngine"` allows the drone to be controlled via setVehiclePose (), keeping the drone in place until the next call. It is especially useful for moving the AirSim drone using an external simulator or on a saved path.

### LocalHostIp Setting
Now when connecting to remote machines you may need to pick a specific Ethernet adapter to reach those machines, for example, it might be
Expand Down