Runtime Common Utilities

class virtual_field.runtime.custom_elastica.control.TargetPoseProportionalControl(elem_index, p_linear_value, p_angular_value, target, is_attached, ramp_up_time=1.0)[source]

PD-style tracking of position (midpoint) and orientation (one segment).

When is_attached() is true, applies external forces at the two nodes \(i\) and \(i+1\) that bound the controlled element, and external torque in local director coordinates at node \(i\).

The linear part uses the segment midpoint \(\mathbf{x}_{\mathrm{mid}} = \tfrac{1}{2}(\mathbf{x}_i + \mathbf{x}_{i+1})\) and position error \(\mathbf{e} = \mathbf{x}_{\mathrm{tar}} - \mathbf{x}_{\mathrm{mid}}\). With ramp factor \(\alpha(t) = \min\bigl(1,\, t / t_{\mathrm{ramp}}\bigr)\), forces are split equally:

\[\mathbf{f}_i = \mathbf{f}_{i+1} = \tfrac{1}{2}\, k_{\mathrm{lin}}\,\alpha\,\mathbf{e}.\]

Directors are stored as row-wise \(\mathbf{D}\in\mathbb{R}^{3\times 3}\) mapping world to local (same convention as PyElastica). Let \(\mathbf{C}=\mathbf{D}^{\mathsf{T}}\) be the corresponding rotation (columns are local axes in world). Orientation error is

\[\mathbf{R}_{\mathrm{err}} = \mathbf{C}_{\mathrm{cur}}^{\mathsf{T}}\mathbf{C}_{\mathrm{tar}} = \mathbf{D}_{\mathrm{cur}}\mathbf{D}_{\mathrm{tar}}^{\mathsf{T}}.\]

The rotation angle \(\theta\) and axis \(\hat{\mathbf{n}}\) are recovered from \(\mathbf{R}_{\mathrm{err}}\) (axis–angle). The applied torque is

\[\boldsymbol{\tau} = k_{\mathrm{ang}}\,\alpha\,\theta\,\hat{\mathbf{n}}\]

in local coordinates, matching external_torques.

See Simple Control Example for a concrete dual-arm usage example (get_target_left / get_target_right).

Parameters:
elem_indexint

Element index along the rod, or negative index counted from the end.

p_linear_valuefloat

\(k_{\mathrm{lin}}\), position gain.

p_angular_valuefloat

\(k_{\mathrm{ang}}\), angular gain.

targetCallable[[], tuple[np.ndarray, np.ndarray]]

Callable returning (position, orientation) with position shape (3,) and orientation shape (3, 3) (row-director matrix).

is_attachedCallable[[], bool]

When false, no forces or torques are applied.

ramp_up_timefloat

\(t_{\mathrm{ramp}}\) for \(\alpha(t)\) (seconds).

apply_forces(system, time=0.0)[source]

Gather targets and apply proportional forces/torques (see class Notes).

Uses simulation time \(t\) for \(\alpha(t)\).

Return type:

None

static compute(external_forces, external_torques, positions, orientations, linear_gain, angular_gain, factor, target_position, target_orientation, idx)[source]

Numba kernel implementing the midpoint force and axis-angle torque update.

Return type:

None