Skip to content

Commit 1b9c930

Browse files
Jackie ChanjonyMarino
authored andcommitted
Working but need to fix payload offset
1 parent 038936b commit 1b9c930

File tree

13 files changed

+320
-34
lines changed

13 files changed

+320
-34
lines changed

client/python/example_user_scripts/payload.py

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88

99
from projectairsim import ProjectAirSimClient, World, PayloadActor, Drone
1010
from projectairsim.utils import projectairsim_log
11-
from typing import List
11+
from projectairsim.image_utils import ImageDisplay
1212

1313

1414
# Async main function to wrap async drone commands
1515
async def main():
1616
# Create a Project AirSim client
1717
client = ProjectAirSimClient()
1818

19+
# Initialize an ImageDisplay object to display camera sub-windows
20+
image_display = ImageDisplay()
21+
1922
try:
2023
# Connect to simulation environment
2124
client.connect()
@@ -27,15 +30,126 @@ async def main():
2730
drone = Drone(client, world, "Drone1")
2831

2932
# Create PayloadActor object
30-
payload = PayloadActor(client, world, "Payload") # spawn like drone in config and watch it fall
33+
payload = PayloadActor(
34+
client, world, "Payload"
35+
) # spawn like drone in config and watch it fall
36+
37+
# ------------------------------------------------------------------------------
38+
39+
# Subscribe to chase camera sensor as a client-side pop-up window
40+
chase_cam_window = "ChaseCam"
41+
image_display.add_chase_cam(chase_cam_window)
42+
client.subscribe(
43+
drone.sensors["Chase"]["scene_camera"],
44+
lambda _, chase: image_display.receive(chase, chase_cam_window),
45+
)
46+
47+
# Subscribe to the downward-facing camera sensor's RGB and Depth images
48+
rgb_name = "RGB-Image"
49+
image_display.add_image(rgb_name, subwin_idx=0)
50+
client.subscribe(
51+
drone.sensors["DownCamera"]["scene_camera"],
52+
lambda _, rgb: image_display.receive(rgb, rgb_name),
53+
)
54+
55+
image_display.start()
56+
57+
# ------------------------------------------------------------------------------
58+
59+
# Set the drone to be ready to fly
60+
drone.enable_api_control()
61+
drone.arm()
62+
63+
# ------------------------------------------------------------------------------
64+
65+
projectairsim_log().info("takeoff_async: starting")
66+
takeoff_task = await drone.takeoff_async()
67+
68+
await takeoff_task
69+
projectairsim_log().info("takeoff_async: completed")
70+
71+
# Command the drone to move up in NED coordinate system at 1 m/s for 3 seconds
72+
move_up_task = await drone.move_by_velocity_async(
73+
v_north=0.0, v_east=0.0, v_down=-1.0, duration=3.0
74+
)
75+
projectairsim_log().info("Move-Up invoked")
76+
77+
await move_up_task
78+
projectairsim_log().info("Move-Up completed")
79+
80+
# Command the drone to move to the payload position
81+
payload_pos = payload.get_kinematics()["pose"]["position"]
82+
83+
projectairsim_log().info("Moving to payload position")
84+
move_to_payload_task = await drone.move_to_position_async(
85+
north=payload_pos["x"], east=payload_pos["y"], down=-3, velocity=1.0
86+
)
87+
await move_to_payload_task
88+
projectairsim_log().info("Moved to payload")
89+
90+
# Command the drone to attach payload
91+
projectairsim_log().info("Attaching payload")
92+
success = drone.attach_payload(payload.name)
93+
projectairsim_log().info(f"Payload was successfully attached: {success}")
94+
95+
# Command the drone to move up in NED coordinate system at 1 m/s for 2 seconds
96+
move_up_task = await drone.move_by_velocity_async(
97+
v_north=0.0, v_east=0.0, v_down=-1.0, duration=2.0
98+
)
99+
projectairsim_log().info("Move-Up invoked")
100+
await move_up_task
101+
projectairsim_log().info("Move-Up completed")
102+
103+
# Command the drone to move north in NED coordinate system at 1 m/s for 2 seconds
104+
move_north_task = await drone.move_by_velocity_async(
105+
v_north=1.0, v_east=1.0, v_down=0.0, duration=4.0
106+
)
107+
projectairsim_log().info("Move-North invoked")
108+
await move_north_task
109+
projectairsim_log().info("Move-North completed")
110+
111+
# Command the drone to move down in NED coordinate system at 1 m/s for 3.5 seconds
112+
move_down_task = await drone.move_by_velocity_async(
113+
v_north=0.0, v_east=0.0, v_down=1.0, duration=3.0
114+
)
115+
projectairsim_log().info("Move-Down invoked")
116+
await move_down_task
117+
projectairsim_log().info("Move-Down completed")
118+
119+
# Command the drone to detach payload
120+
projectairsim_log().info("Detaching payload")
121+
success = drone.detach_payload()
122+
projectairsim_log().info(f"Payload was successfully detached: {success}")
123+
124+
# Command the drone to move north in NED coordinate system at 1 m/s for 1 second
125+
move_north_task = await drone.move_by_velocity_async(
126+
v_north=1.0, v_east=1.0, v_down=0.0, duration=1.0
127+
)
128+
projectairsim_log().info("Move-North invoked")
129+
await move_north_task
130+
projectairsim_log().info("Move-North completed")
131+
132+
projectairsim_log().info("land_async: starting")
133+
land_task = await drone.land_async()
134+
await land_task
135+
projectairsim_log().info("land_async: completed")
136+
137+
# ------------------------------------------------------------------------------
138+
139+
# Shut down the drone
140+
drone.disarm()
141+
drone.disable_api_control()
31142

143+
# ------------------------------------------------------------------------------
32144

145+
# logs exception on the console
33146
except Exception as err:
34147
projectairsim_log().error(f"Exception occurred: {err}", exc_info=True)
35148

36149
finally:
37150
# Always disconnect from the simulation environment to allow next connection
38151
client.disconnect()
152+
image_display.stop()
39153

40154

41155
if __name__ == "__main__":

client/python/example_user_scripts/sim_config/payload_actor.jsonc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"name": "Frame",
55
"inertial": {
6-
"mass": 1.0,
6+
"mass": 0.2,
77
"inertia": {
88
"type": "geometry",
99
"geometry": {

client/python/example_user_scripts/sim_config/scene_payload_actor.jsonc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"type": "payload_actor",
1717
"name": "Payload",
1818
"origin": {
19-
"xyz": "1.0 8.0 -5.0",
19+
"xyz": "5.0 8.0 -4.0",
2020
"rpy-deg": "0 0 0"
2121
},
2222
"payload-actor-config": "payload_actor.jsonc"

client/python/projectairsim/src/projectairsim/drone.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,8 @@ def set_external_force(self, ext_force: List[float]) -> bool:
15271527

15281528
def attach_payload(self, payload_id: str) -> bool:
15291529
"""
1530-
Attach a payload actor in the scene to a position 0.1m below the drone.
1530+
Attach a payload actor in the scene below the drone. The position offset between
1531+
the drone and payload at the time of this call will be saved.
15311532
15321533
Args:
15331534
payload_id (str): the id of the payload actor to attach
@@ -1541,4 +1542,19 @@ def attach_payload(self, payload_id: str) -> bool:
15411542
"version": 1.0,
15421543
}
15431544
success = self.client.request(attach_payload_req)
1545+
return success
1546+
1547+
def detach_payload(self) -> bool:
1548+
"""
1549+
Detaches the payload actor from the drone.
1550+
1551+
Returns:
1552+
bool: True if payload is detached successfully
1553+
"""
1554+
detach_payload_req: Dict = {
1555+
"method": f"{self.world_parent_topic}/DetachPayloadActor",
1556+
"params": {"drone_name": self.name},
1557+
"version": 1.0,
1558+
}
1559+
success = self.client.request(detach_payload_req)
15441560
return success

core_sim/include/core_sim/actor/payload_actor.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class PayloadActor : public Actor {
4848
void UpdateKinematics(const Kinematics& kinematics);
4949
const Environment& GetEnvironment() const;
5050
void UpdateEnvironment();
51+
const Pose& GetPoseOffset() const;
52+
void SetPoseOffset(const Pose& offset);
5153

5254
const CollisionInfo& GetCollisionInfo() const;
5355
void UpdateCollisionInfo(const CollisionInfo& collision_info);
@@ -60,6 +62,9 @@ class PayloadActor : public Actor {
6062

6163
const Wrench& GetDragFaceWrench() const;
6264
void SetDragFaceWrench(const Wrench& drag_wrench);
65+
const Matrix3x3& GetInertiaMatrix() const;
66+
const float GetMass() const;
67+
void SetMass(const float mass);
6368

6469
void BeginUpdate();
6570
void EndUpdate();
@@ -76,6 +81,10 @@ class PayloadActor : public Actor {
7681

7782
void Load(ConfigJson config_json) override;
7883

84+
const Kinematics& ComputeAttachedKinematics(
85+
const Kinematics& kinematics) const;
86+
void ComputeInertiaMatrix();
87+
7988
class Impl;
8089
class Loader;
8190
};

core_sim/include/core_sim/actor/robot.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class Robot : public Actor {
9090
void SetController(std::unique_ptr<IController> controller);
9191

9292
void SetPayloadActor(PayloadActor& payload_actor);
93+
PayloadActor* GetPayloadActor() const;
94+
void ClearPayloadActor();
9395

9496
void PublishRobotPose(const PoseMessage& pose);
9597

@@ -155,8 +157,6 @@ class Robot : public Actor {
155157

156158
void Load(ConfigJson config_json) override;
157159

158-
const Kinematics& ComputeAttachedKinematics() const;
159-
160160
class Impl;
161161
class Loader;
162162
};

0 commit comments

Comments
 (0)