airsim_client/clients/
car_client.rs

1use async_std::net::ToSocketAddrs;
2use msgpack_rpc::Utf8String;
3use rmpv::Value;
4
5use crate::error::NetworkResult;
6
7use super::airsim_client::AirsimClient;
8
9pub struct CarClient {
10    airsim_client: AirsimClient,
11    vehicle_name: &'static str,
12}
13
14impl CarClient {
15    pub async fn connect(addrs: impl ToSocketAddrs, vehicle_name: &'static str) -> NetworkResult<Self> {
16        let airsim_client = AirsimClient::connect(addrs, vehicle_name).await?;
17        Ok(Self {
18            airsim_client,
19            vehicle_name,
20        })
21    }
22
23    /// Reset the vehicle to its original starting state
24    ///
25    /// Note that you must call `enable_ap, Some(vehicle_name)i_control` and `arm_disarm` again after the call to reset
26    #[inline(always)]
27    pub async fn reset(&self) -> NetworkResult<bool> {
28        self.airsim_client.reset().await
29    }
30
31    /// If connection is established then this call will return `True` otherwise
32    /// the request will be blocked until timeout (default value)
33    #[inline(always)]
34    pub async fn ping(&self) -> NetworkResult<bool> {
35        self.airsim_client.ping().await
36    }
37
38    #[inline(always)]
39    pub async fn confirm_connection(&self) -> NetworkResult<bool> {
40        self.airsim_client.confirm_connection().await
41    }
42
43    /// Enables or disables API control for vehicle corresponding to vehicle_name
44    ///
45    /// args:
46    ///     is_enabled (bool): True to enable, False to disable API control
47    ///     vehicle_name (Option<String>): Name of the vehicle to send this command to
48    #[inline(always)]
49    pub async fn enable_api_control(&self, is_enabled: bool) -> NetworkResult<bool> {
50        self.airsim_client
51            .enable_api_control(is_enabled, Some(self.vehicle_name))
52            .await
53    }
54
55    /// Returns true if API control is established.
56    ///
57    /// If false (which is default) then API calls would be ignored. After a successful call
58    /// to `enableApiControl`, `isApiControlEnabled` should return true.
59    ///
60    /// args:
61    ///     vehicle_name (Option<String>): Name of the vehicle to send this command to
62    #[inline(always)]
63    pub async fn is_api_control_enabled(&self, is_enabled: bool) -> NetworkResult<bool> {
64        self.airsim_client
65            .is_api_control_enabled(is_enabled, Some(self.vehicle_name))
66            .await
67    }
68
69    /// Returns true if API control is established.
70    ///
71    /// If false (which is default) then API calls would be ignored. After a successful call
72    /// to `enableApiControl`, `isApiControlEnabled` should return true.
73    ///
74    /// args:
75    ///     arm (bool): True to arm, False to disarm the vehicle
76    ///     vehicle_name (Option<String>): Name of the vehicle to send this command to
77    #[inline(always)]
78    pub async fn arm_disarm(&self, arm: bool) -> NetworkResult<bool> {
79        self.airsim_client.arm_disarm(arm, Some(self.vehicle_name)).await
80    }
81
82    /// Takeoff vehicle to 3m above ground. Vehicle should not be moving when this API is used
83    ///
84    /// Args:
85    ///     timeout_sec (Option<u64>): Timeout for the vehicle to reach desired altitude
86    ///     vehicle_name (Option<String>): Name of the vehicle to send this command to
87    pub async fn take_off_async(&self, timeout_sec: u64) -> NetworkResult<bool> {
88        let vehicle_name: Utf8String = self.vehicle_name.into();
89
90        self.airsim_client
91            .unary_rpc(
92                "takeoff".into(),
93                Some(vec![Value::Integer(timeout_sec.into()), Value::String(vehicle_name)]),
94            )
95            .await
96            .map(|response| response.result.is_ok() && response.result.unwrap().as_bool() == Some(true))
97    }
98}