.. _servoj_rt: servoj_rt ------------------------------------------ This function performs **real-time joint position control** from an external controller. It commands the robot joints to move toward the target position at each RT cycle based on the target position, velocity, acceleration, and interpolation time. **Definition** |br| ``DRFLEx.h`` within class `CDRFLEx`, public section .. code-block:: cpp bool servoj_rt(float fTargetPos[NUM_JOINT], float fTargetVel[NUM_JOINT], float fTargetAcc[NUM_JOINT], float fTargetTime) { return _servoj_rt(_rbtCtrlUDP, fTargetPos, fTargetVel, fTargetAcc, fTargetTime); }; **Caution** - Communication latency or jitter produces jerky motion. - ``fTargetTime`` is not the send interval. See the second **Caution** section below for how to choose it. **Parameter** .. list-table:: :widths: 25 20 20 35 :header-rows: 1 * - **Parameter Name** - **Data Type** - **Default Value** - **Description** * - fTargetPos - float[6] - - - Target joint position [deg]. * - fTargetVel - float[6] - - - Target joint velocity [deg/s]. |br| If set to **None (-10000)**, velocity is automatically computed from ``fTargetPos``. * - fTargetAcc - float[6] - - - Target joint acceleration [deg/s²]. |br| If set to **None (-10000)**, acceleration is automatically computed. * - fTargetTime - float - - - Target motion duration [s]. **Note** - This command is **asynchronous**. - The inner motion profile interpolates the path from current state to ``fTargetPos`` at ``fTargetTime`` using ``fTargetVel`` and ``fTargetAcc``. - On releases with the 0.001 s minimum, if ``fTargetTime`` ≤ controller cycle period (~1 ms), |br| the robot moves directly to the target without interpolation. - If the next command is not received before reaching ``fTargetPos``, the robot decelerates to a stop. On DRCF v2 it uses the joint acceleration set by :ref:`set_accj_rt `, or the joint acceleration limit of the safety settings when that value is 0. On DRCF v3 it always uses the joint acceleration limit of the safety settings. - :ref:`set_velj_rt ` and :ref:`set_accj_rt ` do not limit the trajectory; it follows ``fTargetPos``, ``fTargetVel``, ``fTargetAcc`` and ``fTargetTime``. To cap joint speed, use the joint velocity limit of the safety settings; exceeding it stops the robot. **Caution** - The current version is **not synchronized** with the system’s operation speed [%]. - ``fTargetTime`` is the time the controller is given to reach ``fTargetPos``, and it is **not** the interval at which commands are sent. Set it comfortably larger than the send interval so consecutive commands overlap; a value at or below the send interval produces jerky motion. - The controller enforces a **minimum** ``fTargetTime`` and raises smaller values to it. Minimum fTargetTime: 0.001 s on DRCF v2.12.4 and v3.3.x. On DRCF v2.12.5 or later and v3.4.0 or later, values below 0.025 s are raised to 0.025 s, and each command then takes fTargetTime + 0.005 s. A value below the minimum is silently replaced, so a value tuned on one controller release must be re-checked on another. - The send interval must match the period declared to :ref:`set_rt_control_input `. Sending more slowly than the declared period trips the input watchdog and the controller ends the session, while ``servoj_rt`` keeps returning 1 because it is asynchronous. **Return** .. list-table:: :widths: 20 80 :header-rows: 1 * - **Value** - **Description** * - 1 - The command was sent. This does not confirm that the controller received or applied it. * - 0 - The command datagram could not be sent. .. note:: This function is asynchronous. It returns without waiting for the controller to accept or reject the command, so a return value of 1 does not confirm that the robot acted on it. Rejected commands and motion warnings and errors are reported through :ref:`set_on_log_alarm `. :ref:`set_on_rt_log_alarm ` reports only RT session messages, so register both callbacks. **Example** .. code-block:: cpp #include #include #include drfl.connect_rt_control("192.168.137.100", 12347); std::string version = "v1.0"; float period = 0.001f; // 1 ms int lossCount = 4; // Configure RT streaming drfl.set_rt_control_input(version, period, lossCount); drfl.set_rt_control_output(version, period, lossCount); drfl.start_rt_control(); float fTargetPos[6] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; float fTargetVel[6] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; float fTargetAcc[6] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; float fTargetTime = 0.03f; // above the controller minimum; see the notes above for (int i = 0; i < 5000; ++i) { // Example: oscillate Joint 1 fTargetPos[0] = 10.f * sin(i * 0.01f); drfl.servoj_rt(fTargetPos, fTargetVel, fTargetAcc, fTargetTime); std::this_thread::sleep_for(std::chrono::milliseconds(1)); } drfl.stop_rt_control(); drfl.disconnect_rt_control(); This example demonstrates how to perform continuous joint streaming control by repeatedly sending ``servoj_rt`` commands at 1 ms intervals. **Tips** - Always run ``servoj_rt`` in a **deterministic loop (1 kHz or lower)**. - Use smoothed joint trajectories or low-pass filtered signals to prevent jerk. - For Cartesian streaming, use :ref:`servol_rt ` instead.