1use std::fmt::Debug;
5
6use serde::Deserialize;
7use serde::Serialize;
8use serde_repr::{Deserialize_repr, Serialize_repr};
9
10use crate::network::MessageCommand;
11
12pub static VERSION: u16 = 5;
13pub static COMMAND_PORT: u16 = 1337;
14
15#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
16#[repr(u32)]
17pub enum RobotCommandEnum {
18    Connect,
19    Move,
20    StopMove,
21    GetCartesianLimit,
22    SetCollisionBehavior,
23    SetJointImpedance,
24    SetCartesianImpedance,
25    SetGuidingMode,
26    SetEeToK,
27    SetNeToEe,
28    SetLoad,
29    SetFilters,
30    AutomaticErrorRecovery,
31    LoadModelLibrary,
32}
33
34#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
35#[repr(u8)]
36pub enum DefaultStatus {
37    Success,
38    CommandNotPossibleRejected,
39}
40
41#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
42#[repr(u8)]
43pub enum ConnectStatus {
44    Success,
45    IncompatibleLibraryVersion,
46}
47
48#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone, PartialEq)]
49#[repr(u8)]
50pub enum MoveStatus {
51    Success,
52    MotionStarted,
53    Preempted,
54    CommandNotPossibleRejected,
55    StartAtSingularPoseRejected,
56    InvalidArgumentRejected,
57    ReflexAborted,
58    EmergencyAborted,
59    InputErrorAborted,
60    Aborted,
61}
62
63#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
64#[repr(u8)]
65pub enum StopMoveStatus {
66    Success,
67    CommandNotPossibleRejected,
68    EmergencyAborted,
69    ReflexAborted,
70    Aborted,
71}
72
73#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
74#[repr(u8)]
75pub enum AutomaticErrorRecoveryStatus {
76    Success,
77    CommandNotPossibleRejected,
78    ManualErrorRecoveryRequiredRejected,
79    ReflexAborted,
80    EmergencyAborted,
81    Aborted,
82}
83
84#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
85#[repr(u8)]
86pub enum LoadModelLibraryStatus {
87    Success,
88    Error,
89}
90
91#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
92#[repr(u8)]
93pub enum GetterSetterStatus {
94    Success,
95    CommandNotPossibleRejected,
96    InvalidArgumentRejected,
97}
98
99#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
100#[repr(packed)]
101pub struct ConnectRequest {
102    pub version: u16,
103    pub udp_port: u16,
104}
105
106impl ConnectRequest {
107    pub fn new(udp_port: u16) -> Self {
108        ConnectRequest {
109            version: VERSION,
110            udp_port,
111        }
112    }
113}
114
115#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
116#[repr(packed)]
117pub struct ConnectRequestWithHeader {
118    pub header: RobotCommandHeader,
119    pub request: ConnectRequest,
120}
121
122impl MessageCommand for ConnectRequestWithHeader {
123    fn get_command_message_id(&self) -> u32 {
124        self.header.get_command_message_id()
125    }
126}
127
128#[derive(Serialize, Deserialize, Debug)]
129pub struct ConnectResponse {
130    pub header: RobotCommandHeader,
131    pub status: ConnectStatus,
132    pub version: u16,
133}
134
135#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
136#[repr(u32)]
137pub enum MoveControllerMode {
138    JointImpedance,
139    CartesianImpedance,
140    ExternalController,
141}
142
143#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
144#[repr(u32)]
145pub enum MoveMotionGeneratorMode {
146    JointPosition,
147    JointVelocity,
148    CartesianPosition,
149    CartesianVelocity,
150}
151
152#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
153#[repr(packed)]
154pub struct MoveDeviation {
155    pub(crate) translation: f64,
156    pub(crate) rotation: f64,
157    pub(crate) elbow: f64,
158}
159
160#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
161#[repr(packed)]
162pub struct MoveRequest {
163    controller_mode: MoveControllerMode,
164    motion_generator_mode: MoveMotionGeneratorMode,
165    maximum_path_deviation: MoveDeviation,
166    maximum_goal_deviation: MoveDeviation,
167}
168
169impl MoveRequest {
170    pub fn new(
171        controller_mode: MoveControllerMode,
172        motion_generator_mode: MoveMotionGeneratorMode,
173        maximum_path_deviation: MoveDeviation,
174        maximum_goal_deviation: MoveDeviation,
175    ) -> Self {
176        MoveRequest {
177            controller_mode,
178            motion_generator_mode,
179            maximum_path_deviation,
180            maximum_goal_deviation,
181        }
182    }
183}
184
185#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
186#[repr(packed)]
187pub struct MoveRequestWithHeader {
188    pub header: RobotCommandHeader,
189    pub request: MoveRequest,
190}
191
192impl MessageCommand for MoveRequestWithHeader {
193    fn get_command_message_id(&self) -> u32 {
194        self.header.get_command_message_id()
195    }
196}
197
198#[derive(Serialize, Deserialize, Debug)]
199pub struct MoveResponse {
200    pub header: RobotCommandHeader,
201    pub status: MoveStatus,
202}
203
204#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
205#[repr(packed)]
206pub struct StopMoveRequestWithHeader {
207    pub header: RobotCommandHeader,
208}
209
210impl MessageCommand for StopMoveRequestWithHeader {
211    fn get_command_message_id(&self) -> u32 {
212        self.header.get_command_message_id()
213    }
214}
215
216#[derive(Serialize, Deserialize, Debug)]
217pub struct StopMoveResponse {
218    pub header: RobotCommandHeader,
219    pub status: StopMoveStatus,
220}
221
222#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
223#[repr(packed)]
224pub struct GetCartesianLimitRequest {
225    pub id: i32,
226}
227
228impl GetCartesianLimitRequest {
229    pub fn new(id: i32) -> Self {
230        GetCartesianLimitRequest { id }
231    }
232}
233
234#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
235#[repr(packed)]
236pub struct GetCartesianLimitRequestWithHeader {
237    pub header: RobotCommandHeader,
238    pub request: GetCartesianLimitRequest,
239}
240
241impl MessageCommand for GetCartesianLimitRequestWithHeader {
242    fn get_command_message_id(&self) -> u32 {
243        self.header.get_command_message_id()
244    }
245}
246
247#[derive(Serialize, Deserialize, Debug)]
248pub struct GetCartesianLimitResponse {
249    pub header: RobotCommandHeader,
250    pub status: GetterSetterStatus,
251    pub object_world_size: [f64; 3],
252    pub object_frame: [f64; 16],
253    pub object_activation: bool,
254}
255
256#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
257#[repr(packed)]
258pub struct SetCollisionBehaviorRequest {
259    pub lower_torque_thresholds_acceleration: [f64; 7],
260    pub upper_torque_thresholds_acceleration: [f64; 7],
261    pub lower_torque_thresholds_nominal: [f64; 7],
262    pub upper_torque_thresholds_nominal: [f64; 7],
263    pub lower_force_thresholds_acceleration: [f64; 6],
264    pub upper_force_thresholds_acceleration: [f64; 6],
265    pub lower_force_thresholds_nominal: [f64; 6],
266    pub upper_force_thresholds_nominal: [f64; 6],
267}
268
269impl SetCollisionBehaviorRequest {
270    #[allow(clippy::too_many_arguments)]
271    pub fn new(
272        lower_torque_thresholds_acceleration: [f64; 7],
273        upper_torque_thresholds_acceleration: [f64; 7],
274        lower_torque_thresholds_nominal: [f64; 7],
275        upper_torque_thresholds_nominal: [f64; 7],
276        lower_force_thresholds_acceleration: [f64; 6],
277        upper_force_thresholds_acceleration: [f64; 6],
278        lower_force_thresholds_nominal: [f64; 6],
279        upper_force_thresholds_nominal: [f64; 6],
280    ) -> Self {
281        SetCollisionBehaviorRequest {
282            lower_torque_thresholds_acceleration,
283            upper_torque_thresholds_acceleration,
284            lower_torque_thresholds_nominal,
285            upper_torque_thresholds_nominal,
286            lower_force_thresholds_acceleration,
287            upper_force_thresholds_acceleration,
288            lower_force_thresholds_nominal,
289            upper_force_thresholds_nominal,
290        }
291    }
292}
293
294#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
295#[repr(packed)]
296pub struct SetCollisionBehaviorRequestWithHeader {
297    pub header: RobotCommandHeader,
298    pub request: SetCollisionBehaviorRequest,
299}
300
301impl MessageCommand for SetCollisionBehaviorRequestWithHeader {
302    fn get_command_message_id(&self) -> u32 {
303        self.header.get_command_message_id()
304    }
305}
306
307pub type SetCollisionBehaviorResponse = SetterResponse;
308
309#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
310#[repr(packed)]
311#[allow(non_snake_case)]
312pub struct SetJointImpedanceRequest {
313    pub K_theta: [f64; 7],
314}
315
316#[allow(non_snake_case)]
317impl SetJointImpedanceRequest {
318    pub fn new(K_theta: [f64; 7]) -> Self {
319        SetJointImpedanceRequest { K_theta }
320    }
321}
322
323#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
324#[repr(packed)]
325pub struct SetJointImpedanceRequestWithHeader {
326    pub header: RobotCommandHeader,
327    pub request: SetJointImpedanceRequest,
328}
329
330impl MessageCommand for SetJointImpedanceRequestWithHeader {
331    fn get_command_message_id(&self) -> u32 {
332        self.header.get_command_message_id()
333    }
334}
335
336pub type SetJointImpedanceResponse = SetterResponse;
337
338#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
339#[repr(packed)]
340#[allow(non_snake_case)]
341pub struct SetCartesianImpedanceRequest {
342    pub K_x: [f64; 6],
343}
344
345#[allow(non_snake_case)]
346impl SetCartesianImpedanceRequest {
347    pub fn new(K_x: [f64; 6]) -> Self {
348        SetCartesianImpedanceRequest { K_x }
349    }
350}
351
352#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
353#[repr(packed)]
354pub struct SetCartesianImpedanceRequestWithHeader {
355    pub header: RobotCommandHeader,
356    pub request: SetCartesianImpedanceRequest,
357}
358
359impl MessageCommand for SetCartesianImpedanceRequestWithHeader {
360    fn get_command_message_id(&self) -> u32 {
361        self.header.get_command_message_id()
362    }
363}
364
365pub type SetCartesianImpedanceResponse = SetterResponse;
366
367#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
368#[repr(packed)]
369#[allow(non_snake_case)]
370pub struct SetGuidingModeRequest {
371    pub guiding_mode: [bool; 6],
372    pub nullspace: bool,
373}
374
375#[allow(non_snake_case)]
376impl SetGuidingModeRequest {
377    pub fn new(guiding_mode: [bool; 6], nullspace: bool) -> Self {
378        SetGuidingModeRequest {
379            guiding_mode,
380            nullspace,
381        }
382    }
383}
384
385#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
386#[repr(packed)]
387pub struct SetGuidingModeRequestWithHeader {
388    pub header: RobotCommandHeader,
389    pub request: SetGuidingModeRequest,
390}
391
392impl MessageCommand for SetGuidingModeRequestWithHeader {
393    fn get_command_message_id(&self) -> u32 {
394        self.header.get_command_message_id()
395    }
396}
397
398pub type SetGuidingModeResponse = SetterResponse;
399
400#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
401#[repr(packed)]
402#[allow(non_snake_case)]
403pub struct SetEeToKRequest {
404    pub EE_T_K: [f64; 16],
405}
406
407#[allow(non_snake_case)]
408impl SetEeToKRequest {
409    pub fn new(EE_T_K: [f64; 16]) -> Self {
410        SetEeToKRequest { EE_T_K }
411    }
412}
413
414#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
415#[repr(packed)]
416pub struct SetEeToKRequestWithHeader {
417    pub header: RobotCommandHeader,
418    pub request: SetEeToKRequest,
419}
420
421impl MessageCommand for SetEeToKRequestWithHeader {
422    fn get_command_message_id(&self) -> u32 {
423        self.header.get_command_message_id()
424    }
425}
426
427pub type SetEeToKResponse = SetterResponse;
428
429#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
430#[repr(packed)]
431#[allow(non_snake_case)]
432pub struct SetNeToEeRequest {
433    pub NE_T_EE: [f64; 16],
434}
435
436#[allow(non_snake_case)]
437impl SetNeToEeRequest {
438    pub fn new(NE_T_EE: [f64; 16]) -> Self {
439        SetNeToEeRequest { NE_T_EE }
440    }
441}
442
443#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
444#[repr(packed)]
445pub struct SetNeToEeRequestWithHeader {
446    pub header: RobotCommandHeader,
447    pub request: SetNeToEeRequest,
448}
449
450impl MessageCommand for SetNeToEeRequestWithHeader {
451    fn get_command_message_id(&self) -> u32 {
452        self.header.get_command_message_id()
453    }
454}
455
456pub type SetNeToEeResponse = SetterResponse;
457
458#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
459#[repr(packed)]
460#[allow(non_snake_case)]
461pub struct SetLoadRequest {
462    pub m_load: f64,
463    pub F_x_Cload: [f64; 3],
464    pub I_Load: [f64; 9],
465}
466
467#[allow(non_snake_case)]
468impl SetLoadRequest {
469    pub fn new(m_load: f64, F_x_Cload: [f64; 3], I_Load: [f64; 9]) -> Self {
470        SetLoadRequest {
471            m_load,
472            F_x_Cload,
473            I_Load,
474        }
475    }
476}
477
478#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
479#[repr(packed)]
480pub struct SetLoadRequestWithHeader {
481    pub header: RobotCommandHeader,
482    pub request: SetLoadRequest,
483}
484
485impl MessageCommand for SetLoadRequestWithHeader {
486    fn get_command_message_id(&self) -> u32 {
487        self.header.get_command_message_id()
488    }
489}
490
491pub type SetLoadResponse = SetterResponse;
492
493#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
494#[repr(packed)]
495#[allow(non_snake_case)]
496pub struct SetFiltersRequest {
497    pub joint_position_filter_frequency: f64,
498    pub joint_velocity_filter_frequency: f64,
499    pub cartesian_position_filter_frequency: f64,
500    pub cartesian_velocity_filter_frequency: f64,
501    pub controller_filter_frequency: f64,
502}
503
504#[allow(non_snake_case)]
505impl SetFiltersRequest {
506    pub fn new(
507        joint_position_filter_frequency: f64,
508        joint_velocity_filter_frequency: f64,
509        cartesian_position_filter_frequency: f64,
510        cartesian_velocity_filter_frequency: f64,
511        controller_filter_frequency: f64,
512    ) -> Self {
513        SetFiltersRequest {
514            joint_position_filter_frequency,
515            joint_velocity_filter_frequency,
516            cartesian_position_filter_frequency,
517            cartesian_velocity_filter_frequency,
518            controller_filter_frequency,
519        }
520    }
521}
522
523#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
524#[repr(packed)]
525pub struct SetFiltersRequestWithHeader {
526    pub header: RobotCommandHeader,
527    pub request: SetFiltersRequest,
528}
529
530impl MessageCommand for SetFiltersRequestWithHeader {
531    fn get_command_message_id(&self) -> u32 {
532        self.header.get_command_message_id()
533    }
534}
535
536pub type SetFiltersResponse = SetterResponse;
537
538#[derive(Serialize, Deserialize, Debug)]
539pub struct SetterResponse {
540    pub header: RobotCommandHeader,
541    pub status: GetterSetterStatus,
542}
543
544pub type AutomaticErrorRecoveryRequestWithHeader = RobotCommandHeader;
545
546#[derive(Serialize, Deserialize, Debug)]
547pub struct AutomaticErrorRecoveryResponse {
548    pub header: RobotCommandHeader,
549    pub status: AutomaticErrorRecoveryStatus,
550}
551
552#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
553#[repr(u8)]
554pub enum LoadModelLibraryArchitecture {
555    X64,
556    X86,
557    Arm,
558    Arm64,
559}
560
561#[derive(Serialize_repr, Deserialize_repr, Debug, Copy, Clone)]
562#[repr(u8)]
563pub enum LoadModelLibrarySystem {
564    Linux,
565    Windows,
566}
567
568#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
569#[repr(packed)]
570pub struct LoadModelLibraryRequest {
571    pub architecture: LoadModelLibraryArchitecture,
572    pub system: LoadModelLibrarySystem,
573}
574
575#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
576#[repr(packed)]
577pub struct LoadModelLibraryRequestWithHeader {
578    pub header: RobotCommandHeader,
579    pub request: LoadModelLibraryRequest,
580}
581
582impl MessageCommand for LoadModelLibraryRequestWithHeader {
583    fn get_command_message_id(&self) -> u32 {
584        self.header.get_command_message_id()
585    }
586}
587
588#[derive(Serialize, Deserialize, Debug)]
589pub struct LoadModelLibraryResponse {
590    pub header: RobotCommandHeader,
591    pub status: LoadModelLibraryStatus,
592}
593
594#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
595#[repr(packed)]
596pub struct RobotCommandHeader {
597    pub command: RobotCommandEnum,
598    pub command_id: u32,
599    pub size: u32,
600}
601
602impl RobotCommandHeader {
603    pub fn new(command: RobotCommandEnum, command_id: u32, size: u32) -> RobotCommandHeader {
604        RobotCommandHeader {
605            command,
606            command_id,
607            size,
608        }
609    }
610}
611
612impl MessageCommand for RobotCommandHeader {
613    fn get_command_message_id(&self) -> u32 {
614        self.command_id
615    }
616}