use crate::protocol::dds::api::error::DdsApiError;
use crate::protocol::dds::api::participant::Participant;
use crate::protocol::dds::api::service::ServiceClient;
use crate::protocol::dds::api::subscription::Subscription;
use crate::protocol::dds::ros2::msgs::action_msgs::{
CancelGoal, CancelGoalRequest, GoalInfo, GoalStatusArray,
};
use crate::protocol::dds::ros2::msgs::builtin_interfaces::Time;
use crate::protocol::dds::ros2::msgs::unique_identifier_msgs::Uuid;
use super::types::{Action, GetResultRequest, GetResultService, SendGoalRequest, SendGoalService};
pub struct ActionClient<A: Action> {
send_goal_client: ServiceClient<SendGoalService<A>>,
get_result_client: ServiceClient<GetResultService<A>>,
cancel_client: ServiceClient<CancelGoal>,
feedback_sub: Subscription<A::Feedback>,
status_sub: Subscription<GoalStatusArray>,
}
impl<A: Action> ActionClient<A> {
pub(crate) fn new(
send_goal_client: ServiceClient<SendGoalService<A>>,
get_result_client: ServiceClient<GetResultService<A>>,
cancel_client: ServiceClient<CancelGoal>,
feedback_sub: Subscription<A::Feedback>,
status_sub: Subscription<GoalStatusArray>,
) -> Self {
Self {
send_goal_client,
get_result_client,
cancel_client,
feedback_sub,
status_sub,
}
}
pub fn send_goal(
&mut self,
participant: &mut Participant,
goal_id: Uuid,
goal: A::Goal,
) -> Result<i64, DdsApiError> {
let req = SendGoalRequest::<A> { goal_id, goal };
self.send_goal_client.send_request(participant, &req)
}
pub fn take_goal_responses(&mut self, participant: &mut Participant) -> Vec<(i64, bool, Time)> {
self.send_goal_client
.take_responses(participant)
.into_iter()
.map(|(seq, resp)| (seq, resp.accepted, resp.stamp))
.collect()
}
pub fn request_result(
&mut self,
participant: &mut Participant,
goal_id: Uuid,
) -> Result<i64, DdsApiError> {
let req = GetResultRequest { goal_id };
self.get_result_client.send_request(participant, &req)
}
pub fn take_results(&mut self, participant: &mut Participant) -> Vec<(i64, i8, A::Result)> {
self.get_result_client
.take_responses(participant)
.into_iter()
.map(|(seq, resp)| (seq, resp.status, resp.result))
.collect()
}
pub fn cancel_goal(
&mut self,
participant: &mut Participant,
goal_id: Uuid,
) -> Result<i64, DdsApiError> {
let req = CancelGoalRequest {
goal_info: GoalInfo {
goal_id,
stamp: Time::default(),
},
};
self.cancel_client.send_request(participant, &req)
}
pub fn take_feedback(&mut self, participant: &mut Participant) -> Vec<A::Feedback> {
participant
.take(&self.feedback_sub)
.into_iter()
.map(|s| s.data)
.collect()
}
pub fn take_status(&mut self, participant: &mut Participant) -> Vec<GoalStatusArray> {
participant
.take(&self.status_sub)
.into_iter()
.map(|s| s.data)
.collect()
}
}