@@ -179,6 +179,9 @@ class Scene::Impl : public ComponentWithTopicsAndServiceMethods {
179179 Vector3 GetWindVelocity ();
180180 void UpdateWindVelocity ();
181181
182+ bool LowerPayloadActorServiceMethod (const std::string& drone_name,
183+ const float dz, const float vz);
184+
182185 std::string CallBackAfter (int t_secs);
183186
184187 void RegisterServiceMethod (const ServiceMethod& method,
@@ -380,6 +383,11 @@ const Vector3 Scene::GetWindVelocity() const {
380383 return pimpl_->GetWindVelocity ();
381384}
382385
386+ bool Scene::LowerPayloadActorServiceMethod (const std::string& drone_name,
387+ const float dz, const float vz) {
388+ return pimpl_->LowerPayloadActorServiceMethod (drone_name, dz, vz);
389+ }
390+
383391void Scene::AddNEDTrajectory (
384392 const std::string& traj_name, const std::vector<float >& time,
385393 const std::vector<float >& pose_x, const std::vector<float >& pose_y,
@@ -505,6 +513,44 @@ void Scene::Impl::UpdateWindVelocity() {
505513 }
506514}
507515
516+ bool Scene::Impl::LowerPayloadActorServiceMethod (const std::string& drone_name,
517+ const float dz,
518+ const float vz) {
519+ TimeSec start = SimClock::Get ()->NowSimSec ();
520+ TimeSec curr_time = start;
521+ TimeSec timeout = 180 ; // 3 minutes seems reasonable
522+
523+ auto & actors = GetActors ();
524+ int actor_idx = GetActorIndex (drone_name);
525+ auto & actor_ref = actors[actor_idx];
526+ auto & actor = static_cast <Robot&>(actor_ref.get ());
527+ PayloadActor* payload_actor = actor.GetPayloadActor ();
528+
529+ if (!payload_actor) {
530+ logger_.LogError (name_, " Drone '%hs' is not attached to a PayloadActor." ,
531+ drone_name.c_str ());
532+ throw Error (" Drone is not attached to a PayloadActor." );
533+ } else {
534+ Vector3 payload_pos = payload_actor->GetPoseOffset ().position ;
535+ float z = payload_pos.z ();
536+ float z_final = z + dz;
537+
538+ while (z < z_final) {
539+ auto payload_collision_info = payload_actor->GetCollisionInfo ();
540+ if (payload_collision_info.has_collided ) break ;
541+
542+ z = z + vz * (SimClock::Get ()->NowSimSec () - curr_time);
543+ Vector3 new_pos (payload_pos.x (), payload_pos.y (), z);
544+ payload_actor->SetPoseOffset (
545+ Pose (new_pos, payload_actor->GetPoseOffset ().orientation ));
546+
547+ if (curr_time - start > timeout) return false ;
548+ curr_time = SimClock::Get ()->NowSimSec ();
549+ } // TODO: split into robot.cpp?
550+ }
551+ return true ;
552+ }
553+
508554void Scene::Impl::SetCallbackPhysicsStart (
509555 const std::function<void ()>& callback) {
510556 physics_start_callback_ = callback;
@@ -917,6 +963,12 @@ void Scene::Impl::RegisterServiceMethods() {
917963 auto get_wind_vel_handler =
918964 get_wind_vel.CreateMethodHandler (&Scene::Impl::GetWindVelocity, *this );
919965 RegisterServiceMethod (get_wind_vel, get_wind_vel_handler);
966+
967+ auto lower_payload_actor =
968+ ServiceMethod (" LowerPayloadActor" , {" drone_name" , " dz" , " vz" });
969+ auto lower_payload_actor_handler = lower_payload_actor.CreateMethodHandler (
970+ &Scene::Impl::LowerPayloadActorServiceMethod, *this );
971+ RegisterServiceMethod (lower_payload_actor, lower_payload_actor_handler);
920972}
921973
922974void Scene::Impl::UnregisterAllServiceMethods () {
0 commit comments