.. _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** - The current **servoj_rt** command is **still in early implementation**. |br| Jerky motion may occur depending on communication latency or jitter. - It is recommended to tune ``fTargetTime`` carefully and use a **slow response speed** |br| or use :ref:`speedj_rt ` instead for smoother motion control. - ``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``. - 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 system decelerates according to the global acceleration value. **Caution** - The current version is **not synchronized** with the system’s operation speed [%]. - Jerky motion may occur if the interval between commands exceeds 1 ms. - ``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 the jerky motion described above. - The controller enforces a **minimum** ``fTargetTime`` and raises smaller values to it: **0.001 s on DRCF v2**, and **0.025 s on DRCF v3**, to which v3 adds a further 0.005 s. A value below the minimum is silently replaced, so a value tuned on one controller generation must be re-checked on the other. - 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. - For continuous position control, consider :ref:`speedj_rt `. **Return** .. list-table:: :widths: 20 80 :header-rows: 1 * - **Value** - **Description** * - 1 - The command datagram was sent. * - 0 - The command datagram could not be sent. .. note:: This function is asynchronous. It returns as soon as the datagram is sent and does not wait 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 faults are reported through :ref:`set_on_rt_log_alarm `. **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.