Skip to content

Commit cd6fcce

Browse files
authored
Merge pull request #8 from CodexLabsLLC/payload
Added function to apply external forces (simple payload) microsoft#4519
2 parents 54a3e73 + 3bb692d commit cd6fcce

20 files changed

+96
-13
lines changed

AirLib/include/api/RpcLibClientBase.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ namespace airlib
161161
bool isRecording();
162162

163163
void simSetWind(const Vector3r& wind) const;
164+
void simSetExtForce(const Vector3r& ext_force) const;
165+
164166
vector<string> listVehicles();
165167

166168
std::string getSettingsString() const;

AirLib/include/api/WorldSimApiBase.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ namespace airlib
8686
virtual bool isRecording() const = 0;
8787

8888
virtual void setWind(const Vector3r& wind) const = 0;
89+
virtual void setExtForce(const Vector3r& ext_force) const = 0;
8990
virtual vector<string> listVehicles() const = 0;
9091

9192
virtual std::string getSettingsString() const = 0;

AirLib/include/common/AirSimSettings.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ namespace airlib
419419
std::string speed_unit_label = "m\\s";
420420
std::map<std::string, std::shared_ptr<SensorSetting>> sensor_defaults;
421421
Vector3r wind = Vector3r::Zero();
422+
Vector3r ext_force = Vector3r::Zero();
422423
CameraSettingMap external_cameras;
423424

424425
std::string settings_text_ = "";
@@ -1208,6 +1209,13 @@ namespace airlib
12081209
wind = createVectorSetting(child_json, wind);
12091210
}
12101211
}
1212+
{
1213+
// External Force Settings
1214+
Settings child_json;
1215+
if (settings_json.getChild("ExternalForce", child_json)) {
1216+
ext_force = createVectorSetting(child_json, ext_force);
1217+
}
1218+
}
12111219
}
12121220

12131221
static void loadDefaultCameraSetting(const Settings& settings_json, CameraSetting& camera_defaults)
@@ -1217,7 +1225,6 @@ namespace airlib
12171225
camera_defaults = createCameraSetting(child_json, camera_defaults);
12181226
}
12191227
}
1220-
12211228
static void loadCameraDirectorSetting(const Settings& settings_json,
12221229
CameraDirectorSetting& camera_director, const std::string& simmode_name)
12231230
{

AirLib/include/physics/FastPhysicsEngine.hpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ namespace airlib
2222
class FastPhysicsEngine : public PhysicsEngineBase
2323
{
2424
public:
25-
FastPhysicsEngine(bool enable_ground_lock = true, Vector3r wind = Vector3r::Zero())
26-
: enable_ground_lock_(enable_ground_lock), wind_(wind)
25+
FastPhysicsEngine(bool enable_ground_lock = true, Vector3r wind = Vector3r::Zero(), Vector3r ext_force = Vector3r::Zero())
26+
: enable_ground_lock_(enable_ground_lock), wind_(wind), ext_force_(ext_force)
2727
{
2828
setName("FastPhysicsEngine");
2929
}
@@ -69,6 +69,11 @@ namespace airlib
6969
{
7070
wind_ = wind;
7171
}
72+
// Set External Force
73+
void setExtForce(const Vector3r& ext_force) override
74+
{
75+
ext_force_ = ext_force;
76+
}
7277

7378
private:
7479
void initPhysicsBody(PhysicsBody* body_ptr)
@@ -88,7 +93,7 @@ namespace airlib
8893

8994
//first compute the response as if there was no collision
9095
//this is necessary to take in to account forces and torques generated by body
91-
getNextKinematicsNoCollision(dt, body, current, next, next_wrench, wind_);
96+
getNextKinematicsNoCollision(dt, body, current, next, next_wrench, wind_, ext_force_);
9297

9398
//if there is collision, see if we need collision response
9499
const CollisionInfo collision_info = body.getCollisionInfo();
@@ -261,8 +266,11 @@ namespace airlib
261266
}
262267
}
263268

264-
static Wrench getDragWrench(const PhysicsBody& body, const Quaternionr& orientation,
265-
const Vector3r& linear_vel, const Vector3r& angular_vel_body, const Vector3r& wind_world)
269+
static Wrench getDragWrench(const PhysicsBody& body,
270+
const Quaternionr& orientation,
271+
const Vector3r& linear_vel,
272+
const Vector3r& angular_vel_body,
273+
const Vector3r& wind_world)
266274
{
267275
//add linear drag due to velocity we had since last dt seconds + wind
268276
//drag vector magnitude is proportional to v^2, direction opposite of velocity
@@ -323,7 +331,7 @@ namespace airlib
323331
}
324332

325333
static void getNextKinematicsNoCollision(TTimeDelta dt, PhysicsBody& body, const Kinematics::State& current,
326-
Kinematics::State& next, Wrench& next_wrench, const Vector3r& wind)
334+
Kinematics::State& next, Wrench& next_wrench, const Vector3r& wind, const Vector3r& ext_force)
327335
{
328336
const real_T dt_real = static_cast<real_T>(dt);
329337

@@ -356,7 +364,11 @@ namespace airlib
356364
avg_angular = current.twist.angular + current.accelerations.angular * (0.5f * dt_real);
357365
const Wrench drag_wrench = getDragWrench(body, current.pose.orientation, avg_linear, avg_angular, wind);
358366

359-
next_wrench = body_wrench + drag_wrench;
367+
// ext_force is defined in world space
368+
Wrench ext_force_wrench = Wrench::zero();
369+
ext_force_wrench.force = ext_force;
370+
371+
next_wrench = body_wrench + drag_wrench + ext_force_wrench;
360372

361373
//Utils::log(Utils::stringf("B-WRN %s: ", VectorMath::toString(body_wrench.force).c_str()));
362374
//Utils::log(Utils::stringf("D-WRN %s: ", VectorMath::toString(drag_wrench.force).c_str()));
@@ -459,6 +471,7 @@ namespace airlib
459471
bool enable_ground_lock_;
460472
TTimePoint last_message_time;
461473
Vector3r wind_;
474+
Vector3r ext_force_;
462475
};
463476
}
464477
} //namespace

AirLib/include/physics/PhysicsEngineBase.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace airlib
2828
}
2929

3030
virtual void setWind(const Vector3r& wind) { unused(wind); };
31+
virtual void setExtForce(const Vector3r& ext_force) { unused(ext_force); };
3132
};
3233
}
3334
} //namespace

AirLib/src/api/RpcLibClientBase.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,11 @@ __pragma(warning(disable : 4239))
620620
RpcLibAdaptorsBase::Vector3r conv_wind(wind);
621621
pimpl_->client.call("simSetWind", conv_wind);
622622
}
623-
623+
void RpcLibClientBase::simSetExtForce(const Vector3r& ext_force) const
624+
{
625+
RpcLibAdaptorsBase::Vector3r conv_ext_force(ext_force);
626+
pimpl_->client.call("simSetExtForce", conv_ext_force);
627+
}
624628
vector<string> RpcLibClientBase::listVehicles()
625629
{
626630
return pimpl_->client.call("listVehicles").as<vector<string>>();

AirLib/src/api/RpcLibServerBase.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,6 @@ namespace airlib
278278
const auto& response = getWorldSimApi()->getDetections(type, CameraDetails(camera_name, vehicle_name, external));
279279
return RpcLibAdaptorsBase::DetectionInfo::from(response);
280280
});
281-
282281
pimpl_->server.bind("reset", [&]() -> void {
283282
//Exit if already resetting.
284283
static bool resetInProgress;
@@ -501,6 +500,10 @@ namespace airlib
501500
getWorldSimApi()->setWind(wind.to());
502501
});
503502

503+
pimpl_->server.bind("simSetExtForce", [&](const RpcLibAdaptorsBase::Vector3r& ext_force) -> void {
504+
getWorldSimApi()->setExtForce(ext_force.to());
505+
});
506+
504507
pimpl_->server.bind("listVehicles", [&]() -> vector<string> {
505508
return getWorldSimApi()->listVehicles();
506509
});

PythonClient/airsim/client.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,17 @@ def getSettingsString(self):
11131113
"""
11141114
return self.client.call('getSettingsString')
11151115

1116-
#----------------------------------- Multirotor APIs ---------------------------------------------
1116+
def simSetExtForce(self, ext_force):
1117+
"""
1118+
Set arbitrary external forces, in World frame, NED direction. Can be used
1119+
for implementing simple payloads.
1120+
1121+
Args:
1122+
ext_force (Vector3r): Force, in World frame, NED direction, in N
1123+
"""
1124+
self.client.call('simSetExtForce', ext_force)
1125+
1126+
# ----------------------------------- Multirotor APIs ---------------------------------------------
11171127
class MultirotorClient(VehicleClient, object):
11181128
def __init__(self, ip = "", port = 41451, timeout_value = 3600):
11191129
super(MultirotorClient, self).__init__(ip, port, timeout_value)
@@ -1618,4 +1628,4 @@ def getCarControls(self, vehicle_name=''):
16181628
CarControls:
16191629
"""
16201630
controls_raw = self.client.call('getCarControls', vehicle_name)
1621-
return CarControls.from_msgpack(controls_raw)
1631+
return CarControls.from_msgpack(controls_raw)

Unity/AirLibWrapper/AirsimWrapper/Source/SimMode/SimModeBase.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ std::unique_ptr<msr::airlib::ApiServerBase> SimModeBase::createApiServer() const
107107
return nullptr;
108108
}
109109

110+
void SimModeBase::setExtForce(const msr::airlib::Vector3r& ext_force) const
111+
{
112+
// should be overridden by derived class
113+
unused(ext_force);
114+
throw std::domain_error("setExtForce not implemented by SimMode");
115+
}
116+
110117
void SimModeBase::setupClockSpeed()
111118
{
112119
//default setup - this should be overridden in derived modes as needed

Unity/AirLibWrapper/AirsimWrapper/Source/SimMode/SimModeBase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class SimModeBase
4848
virtual void continueForTime(double seconds);
4949
virtual void continueForFrames(uint32_t frames);
5050
virtual void setWind(const msr::airlib::Vector3r& wind) const;
51+
virtual void setExtForce(const msr::airlib::Vector3r& ext_force) const;
5152
void startApiServer();
5253
void stopApiServer();
5354
bool isApiServerStarted();

Unity/AirLibWrapper/AirsimWrapper/Source/SimMode/SimModeWorldBase.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ std::unique_ptr<SimModeWorldBase::PhysicsEngineBase> SimModeWorldBase::createPhy
6767
else {
6868
physics_engine.reset(new msr::airlib::FastPhysicsEngine());
6969
}
70+
71+
physics_engine->setExtForce(getSettings().ext_force);
7072
}
7173
else if (physics_engine_name == "ExternalPhysicsEngine") {
7274
physics_engine.reset(new msr::airlib::ExternalPhysicsEngine());
@@ -98,6 +100,11 @@ void SimModeWorldBase::setWind(const msr::airlib::Vector3r& wind) const
98100
physics_engine_->setWind(wind);
99101
}
100102

103+
void SimModeWorldBase::setExtForce(const msr::airlib::Vector3r& ext_force) const
104+
{
105+
physics_engine_->setExtForce(ext_force);
106+
}
107+
101108
void SimModeWorldBase::updateDebugReport(msr::airlib::StateReporterWrapper& debug_reporter)
102109
{
103110
unused(debug_reporter);

Unity/AirLibWrapper/AirsimWrapper/Source/SimMode/SimModeWorldBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ class SimModeWorldBase : public SimModeBase
3636
virtual bool isPaused() const override;
3737
virtual void pause(bool is_paused) override;
3838
virtual void continueForTime(double seconds) override;
39-
4039
virtual void setWind(const msr::airlib::Vector3r& wind) const override;
40+
virtual void setExtForce(const msr::airlib::Vector3r& ext_force) const override;
4141

4242
private:
4343
std::unique_ptr<msr::airlib::PhysicsWorld> physics_world_;

Unity/AirLibWrapper/AirsimWrapper/Source/WorldSimApi.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ bool WorldSimApi::testLineOfSightBetweenPoints(const msr::airlib::GeoPoint& poin
279279
return false;
280280
}
281281

282+
void WorldSimApi::setExtForce(const msr::airlib::Vector3r& ext_force) const
283+
{
284+
simmode_->setExtForce(ext_force);
285+
}
286+
282287
std::vector<msr::airlib::GeoPoint> WorldSimApi::getWorldExtents() const
283288
{
284289
std::vector<msr::airlib::GeoPoint> result;

Unity/AirLibWrapper/AirsimWrapper/Source/WorldSimApi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class WorldSimApi : public msr::airlib::WorldSimApiBase
2121
virtual std::string spawnObject(const std::string& object_name, const std::string& load_component, const Pose& pose, const Vector3r& scale, bool physics_enabled, bool is_blueprint) override { return ""; };
2222
virtual bool destroyObject(const std::string& object_name) override { return false; };
2323
virtual std::vector<std::string> listAssets() const override;
24+
virtual void setExtForce(const Vector3r& ext_force) const override;
2425

2526
virtual bool isPaused() const override;
2627
virtual void reset() override;

Unreal/Plugins/AirSim/Source/SimMode/SimModeBase.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,13 @@ void ASimModeBase::setWind(const msr::airlib::Vector3r& wind) const
312312
throw std::domain_error("setWind not implemented by SimMode");
313313
}
314314

315+
void ASimModeBase::setExtForce(const msr::airlib::Vector3r& ext_force) const
316+
{
317+
// should be overridden by derived class
318+
unused(ext_force);
319+
throw std::domain_error("setExtForce not implemented by SimMode");
320+
}
321+
315322
std::unique_ptr<msr::airlib::ApiServerBase> ASimModeBase::createApiServer() const
316323
{
317324
//this will be the case when compilation with RPCLIB is disabled or simmode doesn't support APIs

Unreal/Plugins/AirSim/Source/SimMode/SimModeBase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class AIRSIM_API ASimModeBase : public AActor
6363
virtual void continueForFrames(uint32_t frames);
6464

6565
virtual void setWind(const msr::airlib::Vector3r& wind) const;
66+
virtual void setExtForce(const msr::airlib::Vector3r& ext_force) const;
6667

6768
virtual void setTimeOfDay(bool is_enabled, const std::string& start_datetime, bool is_start_datetime_dst,
6869
float celestial_clock_speed, float update_interval_secs, bool move_sun);

Unreal/Plugins/AirSim/Source/SimMode/SimModeWorldBase.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ std::unique_ptr<ASimModeWorldBase::PhysicsEngineBase> ASimModeWorldBase::createP
7474
}
7575

7676
physics_engine->setWind(getSettings().wind);
77+
physics_engine->setExtForce(getSettings().ext_force);
7778
}
7879
else if (physics_engine_name == "ExternalPhysicsEngine") {
7980
physics_engine.reset(new msr::airlib::ExternalPhysicsEngine());
@@ -136,6 +137,11 @@ void ASimModeWorldBase::setWind(const msr::airlib::Vector3r& wind) const
136137
physics_engine_->setWind(wind);
137138
}
138139

140+
void ASimModeWorldBase::setExtForce(const msr::airlib::Vector3r& ext_force) const
141+
{
142+
physics_engine_->setExtForce(ext_force);
143+
}
144+
139145
void ASimModeWorldBase::updateDebugReport(msr::airlib::StateReporterWrapper& debug_reporter)
140146
{
141147
unused(debug_reporter);

Unreal/Plugins/AirSim/Source/SimMode/SimModeWorldBase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class AIRSIM_API ASimModeWorldBase : public ASimModeBase
3434
virtual void continueForFrames(uint32_t frames) override;
3535

3636
virtual void setWind(const msr::airlib::Vector3r& wind) const override;
37+
virtual void setExtForce(const msr::airlib::Vector3r& ext_force) const override;
3738

3839
protected:
3940
void startAsyncUpdator();

Unreal/Plugins/AirSim/Source/WorldSimApi.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,11 @@ void WorldSimApi::setWind(const Vector3r& wind) const
719719
simmode_->setWind(wind);
720720
}
721721

722+
void WorldSimApi::setExtForce(const Vector3r& ext_force) const
723+
{
724+
simmode_->setExtForce(ext_force);
725+
}
726+
722727
std::vector<std::string> WorldSimApi::listVehicles() const
723728
{
724729
std::vector<std::string> vehicle_names;

Unreal/Plugins/AirSim/Source/WorldSimApi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class WorldSimApi : public msr::airlib::WorldSimApiBase
7575
virtual bool isRecording() const override;
7676

7777
virtual void setWind(const Vector3r& wind) const override;
78+
virtual void setExtForce(const Vector3r& ext_force) const override;
7879
virtual bool createVoxelGrid(const Vector3r& position, const int& x_size, const int& y_size, const int& z_size, const float& res, const std::string& output_file) override;
7980
virtual std::vector<std::string> listVehicles() const override;
8081

0 commit comments

Comments
 (0)