Skip to content

Commit

Permalink
Merge pull request #3626 from jonyMarino/pr/external_physics_engine
Browse files Browse the repository at this point in the history
External physics engine
  • Loading branch information
Jonathan authored Apr 30, 2021
2 parents a2acbf4 + 8232efe commit 0b936af
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 5 deletions.
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

0 comments on commit 0b936af

Please sign in to comment.