Skip to main content

franka/robot/
active.rs

1//! The [`ActiveControl`](crate::robot::active_control) entry points of [`Robot`]
2//! (`franka::Robot::startTorqueControl` and friends).
3
4use super::*;
5
6impl Robot {
7    // -- ActiveControl -------------------------------------------------------------------
8
9    /// Starts an external torque control process driven by
10    /// [`ActiveTorqueControl::read_once`] / [`ActiveTorqueControl::write_once`].
11    ///
12    /// # Errors
13    /// [`FrankaError::InvalidOperation`] if another control or read operation is running,
14    /// [`FrankaError::Control`] if a motion is already running on the robot.
15    pub fn start_torque_control(&self) -> FrankaResult<ActiveTorqueControl<'_>> {
16        let lock = self.acquire_control_lock()?;
17        // FCI v5 has no torque-only motion generator mode; `torque_only_motion_mode` picks the
18        // zero-velocity joint velocity generator libfranka 0.9.2 uses instead.
19        let motion_id = self.start_motion(
20            MoveControllerMode::ExternalController,
21            self.robot.torque_only_motion_mode(),
22        )?;
23        Ok(ActiveTorqueControl::new(&self.robot, motion_id, lock))
24    }
25
26    /// Starts an externally driven joint position motion.
27    pub fn start_joint_position_control(
28        &self,
29        controller_mode: MoveControllerMode,
30    ) -> FrankaResult<ActiveMotionGenerator<'_, JointPositions>> {
31        self.start_active_motion(controller_mode, MoveMotionGeneratorMode::JointPosition)
32    }
33
34    /// Starts an externally driven joint velocity motion.
35    pub fn start_joint_velocity_control(
36        &self,
37        controller_mode: MoveControllerMode,
38    ) -> FrankaResult<ActiveMotionGenerator<'_, JointVelocities>> {
39        self.start_active_motion(controller_mode, MoveMotionGeneratorMode::JointVelocity)
40    }
41
42    /// Starts an externally driven Cartesian pose motion.
43    pub fn start_cartesian_pose_control(
44        &self,
45        controller_mode: MoveControllerMode,
46    ) -> FrankaResult<ActiveMotionGenerator<'_, CartesianPose>> {
47        self.start_active_motion(controller_mode, MoveMotionGeneratorMode::CartesianPosition)
48    }
49
50    /// Starts an externally driven Cartesian velocity motion.
51    pub fn start_cartesian_velocity_control(
52        &self,
53        controller_mode: MoveControllerMode,
54    ) -> FrankaResult<ActiveMotionGenerator<'_, CartesianVelocities>> {
55        self.start_active_motion(controller_mode, MoveMotionGeneratorMode::CartesianVelocity)
56    }
57
58    fn start_active_motion<T: ActiveMotionInput>(
59        &self,
60        controller_mode: MoveControllerMode,
61        motion_generator_mode: MoveMotionGeneratorMode,
62    ) -> FrankaResult<ActiveMotionGenerator<'_, T>> {
63        let lock = self.acquire_control_lock()?;
64        let motion_id = self.start_motion(controller_mode, motion_generator_mode)?;
65        Ok(ActiveMotionGenerator::new(
66            &self.robot,
67            motion_id,
68            lock,
69            controller_mode,
70        ))
71    }
72
73    fn start_motion(
74        &self,
75        controller_mode: MoveControllerMode,
76        motion_generator_mode: MoveMotionGeneratorMode,
77    ) -> FrankaResult<u32> {
78        let deviation = Deviation::new(
79            DEFAULT_DEVIATION.0,
80            DEFAULT_DEVIATION.1,
81            DEFAULT_DEVIATION.2,
82        );
83        self.robot
84            .start_motion(controller_mode, motion_generator_mode, deviation, deviation)
85    }
86}