Actin  Version 5.5.5 Software for Robotics Simulation and Control
EcScript

# Introduction

EcScript provide motion primitives, sequences, and a scripting interface for controlling manipulators. The EcScript adopts LISP-like syntax. An EcScript is a list of command token, parameters, and EcScripts:

<motion_script> := ([COMMAND_TOKEN] [<parameter> ...] [<motion_script> ...])


Script commands are handled by corresponding classes, which are all derived from EcMotionScriptObject. Parameters are literals/variables of various types supported by EcScript (see the next section).

There are two ways to use the motion library and EcScript:

The relationship between EcScript, EcMotionScriptObject, and EcBaseControlSystemModifier is illustrated below:

The relationship between EcScript, EcMotionScriptObject, and EcBaseControlSystemModifier.

The design concept of the motion planning library is there should be no dynamic memory allocation during runtime of an EcScript.

# Variable

EcScript supports the following basic types:

• Boolean (bool): used for condition, digital IO, etc. See Define Boolean.
• Unsigned Integer (u32): used for manipulator index, end-effector set index, loop counter, etc. Hexdecimal is supported. See Define U32.
• Double precision floating-point (real): used for tolerance, speed factor, etc. See Define Real.
• String (string): used for name, path, etc. See Define String.

EcScript also supports the following compound types:

• Translation (trans): a list of 3 real values. See Define Translation.
• Orientation (rot): a list of rotation type and 3 or 4 real values. See Define Orientation.
• Pose (pose): a list of translation and orientation. Used for pose or coordinate transformation. See Define Pose.
• Real vector (real_vec): a list of real values. Usually used for joint positions or velocities. See Define Real Vector.
• U32 vector (u32_vec): a list of U32 values. Usually used for link indices. See Define U32 Vector.

For the real value or the real values in the compound types, users can specify the unit and they can be mixed together. By default, Actin always uses meter and radian internally. By appending a unit to the end of a real value, EcScript parser will multiply the value with corresponding coefficients.

The following units are supported:

# Motion Primitives

## Move Joint

This command is handled by EcEndEffectorMotionMoveJoint.

Command format 1:

1 (move_joint <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>] <cmd_joints:real_vec> (<speed_factor:real> <acceleration_factor:real>) <position_tolerance:real>)

Command format 2:

1 (move_joint <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>] <cmd_joints:real_vec> (<speed_factor:real> <acceleration_factor:real>) (<position_tolerance:real> <velocity_tolerance:real>))

move_joint moves the manipulator of index <manip_id> in joint space to <cmd_joints> with speed factor <speed_factor> and acceleration factor <acceleration_factor>. When using command format 1, the command returns succeeded if the joint position error (difference between current and command joint positions) is smaller than <position_tolerance>. When using command format 2, the command returns succeeded if both the joint position error is smaller than <position_tolerance>, and the joint velocity error (difference between current and zero joint velocities) is smaller than <velocity_tolerance>.

If the <ee_set_id> and <ee_id> are not provided, the command will use the first end-effector in the joint control end-effector set by default. If the <ee_set_id> and <ee_id> are provided, the set must exist and the end-effector of that set must be a joint control end-effector. In addition, the size of <cmd_joints> must match the degree-of-constraints of the joint control end-effector. Or the command will fail.

Example:

1 (move_joint 0 (0.0 45.0deg 60.0deg 0.0 -90.0deg 0.0) (1.0 1.0) 1e-3)

## Move Joint Relative

Command format 1:

1 (move_joint_rel <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>] <cmd_joints:real_vec> (<speed_factor:real> <acceleration_factor:real>) <position_tolerance:real>)

Command format 2:

1 (move_joint_rel <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>] <cmd_joints:real_vec> (<speed_factor:real> <acceleration_factor:real>) (<position_tolerance:real> <velocity_tolerance:real>))

move_joint_rel moves the manipulator of index <manip_id> in joint space to current joint positions + <cmd_joints>.

## Move Joint Mixed

Command format 1:

1 (move_joint_mix <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>] <cmd_joints:real_vec> <relative_flag> (<speed_factor:real> <acceleration_factor:real>) <position_tolerance:real>)

Command format 2:

1 (move_joint_mix <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>] <cmd_joints:real_vec> <relative_flag> (<speed_factor:real> <acceleration_factor:real>) (<position_tolerance:real> <velocity_tolerance:real>))

move_joint_mix moves the manipulator of index <manip_id> in joint space. <relative_flag> is a vector of 0 or 1. The size must be the same as <cmd_joints>. If the flag is 0 (absolute), move_joint_mix moves the joint to the value in <cmd_joints>. If the flag is 1 (relative), move_joint_mix moves the joint to current position + the value in <cmd_joints>.

Example:

1 (move_joint_mix 0 (0.0 45.0deg 60.0deg 0.0 -90.0deg 0.0) (0 0 0 1 1 1) (1.0 1.0) 1e-3)

This command moves the first 3 joints to 0deg, 45deg, 60deg, and change the position of the 5th joint by -90deg.

## Move Pose

Move pose moves the robot in Cartesian space of the end effector. This command is handled by EcEndEffectorMotionMovePose

Command format 1:

1 (move_pose <manip_id:u32> <ee_set_id:u32> <ee_id:u32> <cmd_pose:pose> (<speed_factor:real> <acceleration_factor:real>) <position_tolerance:real>)

Command format 2:

1 (move_pose <manip_id:u32> <ee_set_id:u32> <ee_id:u32> <cmd_pose:pose> (<speed_factor:real> <acceleration_factor:real>) (<position_tolerance:real> <velocity_tolerance:real>))

Example command:

1 (move_pose 0 0 0 ((-0.3 0.0 0.6) (0.0 0.0 0.0)) (1.0 1.0) 0.001)

This command moves the position of Robot 0 to pose (-0.3m 0m 0.6m 0deg 0deg 0deg) with maximum speed and acceleration with position tolerance 0.001.

## Move Pose Relative

Move pose relative moves the robot's end-effector by a given delta pose from its current pose. The delta pose can be in the system coordinate frame or the end-effector coordinate frame. This command is handled by EcEndEffectorMotionMovePoseRelative.

Command format 1:

1 (move_pose_rel <manip_id:u32> <ee_set_id:u32> <ee_id:u32> <delta_pose:_pose> (<speed_factor:real> <acceleration_factor:real>) <position_tolerance:real> [<use_ee_frame:bool>])

Command format 2:

1 (move_pose_rel <manip_id:u32> <ee_set_id:u32> <ee_id:u32> <delta_pose:_pose> (<speed_factor:real> <acceleration_factor:real>) (<position_tolerance:real> <velocity_tolerance:real>) [<use_ee_frame:bool>])

If <use_ee_frame> is provided and true, then <delta_pose> is provided in the end-effector coordinate frame, otherwise, it is provided in the system coordinate frame.

Example command:

1 (move_pose_rel 0 2 0 ((-0.1 0.0 0.6) (0.0 0.0 45.0deg)) (1.0 1.0) 0.001 TRUE)

This command moves the position of Robot 0 from its current pose to the new pose that is the homogeneous transformation of the current pose and the provided delta pose, i.e., the translation and rotation are from the current end-effector frame. The example command will move the end-effector by -0.1m in its current x-direction and 0.6m in its current z-direction with a rotation of 45deg about its current z-axis.

## Speed

Speed moves the robot with joint space or end-effector space velocity if [<ee_set_id> <ee_id>] are provided. This command is handled by EcEndEffectorMotionSpeed.

Command format:

1 (speed <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>] <cmd_speed:real_vec> [<acceleration_factor:real>] <tolerance:real>)

Example command:

1 (speed 0 (10deg 10deg 10deg 10deg 10deg 10deg) 0.5 0.001)

This command drives the joint velocity of Robot 0 to (10deg/s 10deg/s 10deg/s 10deg/s 10deg/s 10deg/s) using half maximum end-effector acceleration.

Example command:

1 (speed_pose 0 1 0 (0 0.02 0 30deg -5deg 0) 0.001)

This command drives the end-effector velocity of Robot 0 to (0m/s 0.02m/s 0m/s 30deg/s -5deg/s 0deg/s) using End-effector Set 1 and maximum end-effector acceleration.

## Stop

Stop motion stops the robot using velocity control. This command is handled by EcEndEffectorMotionStop.

Command format:

1 (stop <manip_id> [<ee_set_id>] <tolerance>)

If the <ee_set_id> is not provided, stop will automatically use the current end-effector set. If the <ee_set_id> is provided, the set must exist or the motion will fail.

Example command:

1 (stop 0 0.001)

This command stops the motion of Robot 0. The tolerance to judge whether the robot has stopped is 0.001.

## Move Linear

Linear interpolation. This command is handled by EcEndEffectorMotionMoveLinear. The difference between this command and move_pose is:

• move_pose requires tolerance and is used alone.
• move_linear can be used in combination with other motions in group_motion_seq.

Command format:

1 (move_linear <manip_id:u32> <ee_set_id:u32> <ee_id:u32> <cmd_pose:pose> (<speed_factor:real> <acceleration_factor:real>) [<blend_radius:real>])

<blend_radius> is only effective when used within group_motion_seq. If not provided, the blend radius is 0 by default.

Example command:

1 (move_linear 0 1 0 ((-150mm 350mm 100mm)(-180deg 0 0)) (0.1 0.1))

This command moves the position of Robot 0, end-effector set 1, end-effector 0 to (-0.15m 0.35m 0.1m), Euler angles (-180.0deg 0.0deg 0.0deg) with speed factor 0.1m.

## Move Circular

Circular interpolation. This command is handled by EcEndEffectorMotionMoveCircular.

Command format (boarder mode):

The boarder mode uses <boarder_point> and <goal_point> [and <goal_orientation>] to define an arc.

1 (move_circular <manip_id:u32> <ee_set_id:u32> <ee_id:u32>
2  (BORDER <boarder_point:trans> <goal_point:trans> [<goal_orientation:rot>])

This mode cannot define a full circle. If the current position and the <goal_point> overlaps, the arc becomes singular and the command will return failed.

Example command:

1 (move_circular 0 1 0
2  (BORDER (0.0 -0.3 0.17) (0.0 -0.25 0.05) (0 0 90deg)) (0.1 1.0))

Command format (center-normal-angle mode):

The center-normal-angle mode uses <center_point>, <normal_vec>, <arc_length> (in central angle) [and <goal_orientation>] to define an arc.

1 (move_circular <manip_id:u32> <ee_set_id:u32> <ee_id:u32>
2  (CNA <center_point:trans> <normal_vec:trans> <arc_length:real> [<goal_orientation:rot>])

This mode can define a full circle and <arc_length> can be greater than 360 degrees.

In both modes, if the <goal_orientation> is provided, move_circular will interpolate orientation from the start to the <goal_orientation>. Otherwise, the orientation will be calculated by rotating the start orientation about the circle normal. <blend_radius> is only effective when used within group_motion_seq. If not provided, the blend radius is 0 by default.

On a UR5, given the goal orientation, the path looks like:

The path of a sample move_circular command with given goal orientation.

Without a goal orientation, the path looks like:

The path of a sample move_circular command without goal orientation.

## Move Helical

Helical interpolation. This command is handled by EcEndEffectorMotionMoveHelical.

Command format:

1 (move_helical <manip_id:u32> <ee_set_id:u32> <ee_id:u32>
2  (<center_point:trans> <normal_vec:trans> <arc_length:real> <pitch:real> [<goal_orientation:rot>])

This command uses <center_point>, <normal_vec>, <arc_length> (in central angle), <pitch> [and <goal_orientation>] to define an helical arc.

If the <goal_orientation> is provided, move_helical will interpolate orientation from the start to the <goal_orientation>. Otherwise, the orientation will be calculated by rotating the start orientation about the helix axis. <blend_radius> is only effective when used within group_motion_seq. If not provided, the blend radius is 0 by default.

Note
The normal vector should be perpendicular with the center-start vector.

On a UR5, given the goal orientation, the path looks like:

The path of a sample move_helical command with given goal orientation.

Without a goal orientation, the path looks like:

The path of a sample move_helical command without goal orientation.

## Move Path

Command format:

1 (move_path <manip_id> <ee_set_id> <ee_id> "filePath" (<speed_factor:real> <acceleration_factor:real>) [<blend_radius:real>])

This command supports moving tool path which is defined in "filePath". Supported tool path format are G-code (.nc) or Energid tool path (not .nc). Environment variables are supported, which must be wrapped in {}. <blend_radius> is only effective when used within group_motion_seq. If not provided, the blend radius is 0 by default. ## Group Motion Sequence Command format: 1 (group_motion_seq <manip_id> 2 [(set_pcs <pcs:pose>] 3 [(move_linear ...)] 4 [(move_circular ...)] 5 ... 6 ) Group motion sequence provides axes group motion control (see also Group Motion Manager). It supports: • Motions: • set_pcs: set the Part Coordinate System (PCS) for move_linear, move_circular, move_helical, and move_path. The following motions will be defined relative to the new PCS. • set_tcp • All other instantaneous scripts. Motions are blended unless set_tcp is in-between. Example command: 1 (group_motion_seq 0 2 (set_pcs ((-50mm 0 0)(0 0 0))) 3 (move_linear 0 1 0 ((-100mm 350mm 100mm)(-180deg 0 0)) (0.1 0.1)) 4 (move_circular 0 1 0 (CNA (-100mm 400mm 100mm) (0 0 1) 90deg) (0.1 0.1)) 5 (set_data_map_u32 "current_id" 2) 6 (set_pcs ((0 0 0)(0 0 0))) 7 (move_linear 0 1 0 ((-100mm 500mm 100mm)(0 -90deg -180deg)) (0.1 0.1)) 8 (move_circular 0 1 0 (CNA (-100mm 500mm 50mm) (1 0 0) -90deg) (0.1 0.1)) 9 (move_linear 0 1 0 ((-100mm 550mm 0mm)(0 -90deg -180deg)) (0.1 0.1)) 10 ) The first move_linear and move_circular are defined relative to the PCS ((-50mm 0 0)(0 0 0)). The U32 data map with key "current_id" will be set to 2 after the first 2 motions are done. The rest are defined relative to the Machine Coordinate System (MCS) since PCS is set to identity. On a UR5, the path looks like: The path of a sample group_motion_seq command. ## Set Active End Effector Set Set the active end effector set of a manipulator. This command is handled by EcManipulatorMotionSetActiveEndEffectorSet. Command format: 1 (set_ee_set <manip_id> <ee_set_id>) Example command: 1 (set_ee_set 1 2) This command sets end effector set 2 as the active end effector set of manipulator 1. ## Set Active Control Description Set the active control description of a manipulator. This command is handled by EcManipulatorMotionSetActiveControlDescription. Command format: 1 (set_control_description <manip_id:u32> <acd_id:u32>) Example command: 1 (set_control_description 0 1) This command sets control description 1 as active control description of manipulator 0. ## Set Active Position Control Method Set the active position control method index for a manipulator. This command is handled by EcManipulatorMotionSetActivePositionControlMethod. Command format: 1 (set_position_control_method <manip_id:u32> <apcm_id:u32>) Example command: 1 (set_position_control_method 0 1) This command sets control method 1 as active position control method of manipulator 0. ## Set Base Speed Factor Set the base speed factor of a manipulator. This command is handled by EcManipulatorMotionSetBaseSpeedFactor. Command format: 1 (set_base_speed_factor <manip_id:u32> <speed_factor:real>) Example format: 1 (set_base_speed_factor 0 0.1) This command sets the base speed factor for Manipulator 0 to 0.1. ## Set Base Acceleration Factor Set the base acceleration factor of a manipulator. This command is handled by EcManipulatorMotionSetBaseAccelerationFactor. Command format: 1 (set_base_accel_factor <manip_id:u32> <accel_factor:real>) Example format: 1 (set_base_accel_factor 0 0.1) This command sets the base acceleration factor of Manipulator 0 to 0.1. ## Set Position State Set the position state of a manipulator. This command is handled by EcManipulatorMotionSetPositionState. Command format: 1 (set_position_state <manip_id:u32> [<base_pose:pose>] [<joint_positions:real_vec>]) If only one of the <base_pose> or <joint_positions> is provided, this command sets the base pose or the joint positions only. The command also updates the base pose of any manipulators that are attached to <manip_id>, and resets the desired end-effector placements of the base and dependent manipulators to current. Example format: 1 (set_position_state 0 ((-0.3 0.0 0.6) (0.0 0.0 0.0)) (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602)) This command sets the manipulator 0's base to pose ((-0.3 0.0 0.6) (0.0 0.0 0.0)), and joints to (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602). Example format: 1 (set_position_state 0 ((-0.3 0.0 0.6) (0.0 0.0 0.0))) This command sets the manipulator 0's base to pose (-0.3 0.0 0.6) (0.0 0.0 0.0). Example format: 1 (set_position_state 0 (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602)) This command sets the manipulator 0's joints to (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602). ## Set Sensed State Feed back the externally sensed position state to the position controller. This command is handled by EcManipulatorMotionSetSensedState. Command format: 1 (set_sensed_state <manip_id:u32> [<base_pose:pose>] [<joint_positions:real_vec>]) If only one of the <base_pose> or <joint_positions> is provided, this command sets the base pose or the joint positions only. The command does not updates the base pose of any manipulators that are attached to <manip_id>, nor resets the desired end-effector placements. Example format: 1 (set_sensed_state 0 ((-0.3 0.0 0.6) (0.0 0.0 0.0)) (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602)) This command sets the manipulator 0's base to pose (-0.3 0.0 0.6) (0.0 0.0 0.0), and joints to (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602). Example format: 1 (set_sensed_state 0 ((-0.3 0.0 0.6) (0.0 0.0 0.0))) This command sets the manipulator 0's base to pose (-0.3 0.0 0.6) (0.0 0.0 0.0). Example format: 1 (set_sensed_state 0 (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602)) This command sets the manipulator 0's joints to (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602). ## Set Tool Offset Set the tool offset (TCP) of an end-effector in the end-effector frame given its index or given the external tool offset index. If the end-effector does not use external tool offset, this command will fail. This command is handled by EcEndEffectorMotionSetTcp. Command format 1 (setting TCP given end-effector index): 1 (set_tcp <manip_id> <ee_set_id> <ee_id> <pose>) Example: 1 (set_tcp 0 0 0 ((0.1 0.0 0.0) (0.0 0.0 0.0))) Command format 2 (setting TCP given the external tool offset index): 1 (set_tcp <manip_id> <tool_offset_id> <pose>) Example: 1 (set_tcp 0 0 ((0.1 0.0 0.0) (0.0 0.0 0.0))) ## Attach/Detach Manipulator To attach a manipulator (dependent) to a link of another manipulator (independent) with the offset calculated using the current state so that the dependent manipulator moves with independent manipulator: 1 (attach_manip <dependent_manip_id> <independent_manip_id> <link_id>) Example command: 1 (attach_manip 1 0 5) This will attach manipulator 1 to link 5 of manipulator 0 at the current state, i.e. manipulator 1 will not move after attachment. To attach a manipulator to a link of another manipulator with a given ofset: 1 (attach_manip <dependent_manip_id> <independent_manip_id> <link_id> <offset>) Note that offset is a pose. Example command: 1 (attach_manip 1 0 5 ((0.1 0.0 0.0) (0.0 0.0 0.0))) This will attach manipulator 1 to link 5 of manipulator 0 with the offset of 0.1 m in X direction. The offset is between the primary frames of link 5 of manipulator 0 and the base link of manipulator 1. This will potentially move manipulator 1 after attachment. To attach a manipulator to a link of another manipulator such that a named frame of on the base link of the dependent manipulator is aligned with a named frame on the link of the independent manipulator: 1 (attach_manip <dependent_manip_id> <dependent_named_frame> <independent_manip_id> <link_id> <independent_named_frame>) Example command: 1 (attach_manip 1 "gripper" 0 5 "gripper") This will attach manipulator 1 to link 5 of manipulator 0 such that the "gripper" named frame on the base link of manipulator 1 is aligned with the "gripper" named frame on link 5 of manipulator 0 and . This will potentially move manipulator 1 after attachment. To attach a manipulator to a link of another manipulator such that a named frame of on the base link of the dependent manipulator is offseted with a named frame on the link of the independent manipulator: 1 (attach_manip <dependent_manip_id> <dependent_named_frame> <independent_manip_id> <link_id> <independent_named_frame> <offset>) Example command: 1 (attach_manip 1 "gripper" 0 5 "gripper" ((0.1 0.0 0.0) (0.0 0.0 0.0))) This will attach manipulator 1 to link 5 of manipulator 0 with the offset of 0.1 m in X direction. The offset is between the "gripper" named frame the base link of manipulator 1 and the "gripper" named frame on link 5 of manipulator 0 and . This will potentially move manipulator 1 after attachment. These commands are handled by EcManipulatorMotionAttachManipulator. For the base link, use BASE. If the attachment results in a chain, this command will return failed. To detach: 1 (detach_manip <dependent_manip_id>) This command is handled by EcManipulatorMotionDetachManipulator. If the dependent manipulator is not currently attached to any manipulator, this command will return failed. Example command: 1 (detach_manip 0) This command detachs dependent manipulator from the manipulator it attached with. ## Exclude/Include Collision To exclude/include collision check between a manipulator and everything else: 1 (exclude_collision/include_collision <manip_id_0>) Example command: 1 (exclude_collision/include_collision 0) This command excludes/includes collision check between manipulator 0 and everything else. To exclude/include collision check between two manipulators: 1 (exclude_collision/include_collision <manip_id_0> <manip_id_1>) Example command: 1 (exclude_collision/include_collision 0 1) This command excludes/includes collision check between manipulator 0 and manipulator 1. To exclude/include collision check between a manipulator and links of another manipulator: 1 (exclude_collision/include_collision <manip_id_0> <manip_id_1> <link_indices>) where, <link_indices> is a U32 vector. Example command: 1 (exclude_collision/include_collision 0 1 (1 2))) This command excludes/includes collision check between manipulator 0 and 1st, and 2nd links of manipulator 1. To exclude/include collision check between a link of a manipulator and links of another manipulator: 1 (exclude_collision/include_collision <manip_id_0> <link_id> <manip_id_1> <link_indices>) Example command: 1 (exclude_collision/include_collision 0 1 1 (1 2))) This command excludes/includes collision check between 1st link of manipulator 0 and 1st, and 2nd links of manipulator 1. To exclude/include collision check between both a manipulator and each of its dependent manipulators against everything else: 1 (exclude_attach_collision/include_atach_collision <manip_id>) Example command: 1 (exclude_attach_collision/include_atach_collision 0) This command excludes/includes collision check between both manipulator 0 and each of its dependent manipulators against everything else. ## RRT Path Planning and Execution Plan a path in joint space using RRT. If a feasible path is found, execute this path. There is also an option to cache the planned path. This command is handled by EcManipulatorMotionRrtPlan. Command format: 1 (rrt_plan <manip_id> <target_joints> [(<param0_name> <param0_value>) ...]) The command will try to find a path in joint space that connect the manipulator's (<manip_id>) current position to the target position (<target_joints>). If a feasible path is found, this path will be executed; otherwise, return failed. Several parameters can be set to further control the planning and the execution. These parameters are optional. For some parameters, if they are absent, default values will be used. For the others, if they are absent, the functionalities won't be used. As shown in the command format, the parameters have to be at the end of the command, but the order within is flexible. The distances are Euclidean distances in joint space， if not otherwise explained. List of Parameters. Parameter Name Description If Absent MaxTime Maximum planning time in seconds. 5.0 (default value) StepSize Distance between adjacent tree nodes. 0.5 (default value) CollisionStepSize Distance between adjacent nodes for collision checking. 0.02 (default value) CollisionThreshold Collision threshold in work space in meters during collision checking. 0.1 (default value) PathShorteningIterations Number of iterations of path shortening. 1 (default value) PathShorteningTolerance Length of the shortest segment considered during path shortening. 0.02 (default value) SpeedFactor Speed factor of move_joint commands in execution. 1.0 (default value) AccelerationFactor Acceleration factor of move_joint commands in execution. 1.0 (default value) Tolerance Tolerance of move_joint commands in execution. 0.001 (default value) CachePath Name of the cached path, and threshold for assertion. Path caching will be skipped. CacheSamplingData Name of the cached seed, and name of the cached number of samples. Sampling data caching will be skipped. Extra note for path caching While most of the parameters need only one <param_value>, there has to be two <param_value>s following CachePath. The first one is the name of the cached path. The command will convert the path into an EcScript string of a series move_joint commands, and will store it into the data map with this name. The second one is the threshold of an assertion. It's only safe to execute the cached path when the robot is near the start position where the planner starts. (Also assume that the environment hasn't change since then.) So an assert command is inserted before those move_joint commands. And the cached path will be executed, only when the Euclidean distance of the joint positions, where the path is executed, and the joint positions, where the path starts, is smaller than this threshold. Extra note for sampling data caching While the other parameters, besides path caching, need only one <param_value>, there has to be two string <param_value>s following CacheSamplingData. The first one is the name of the cached seed value (from the random number generator). The second one is the name of the cached number of samples. These values can be retrieved from the data map for data collection in order to recreate the random sequence that was used to create the tree for troubleshooting or later analysis. Example command: 1 (rrt_plan 0 (-1.46939 -0.443042 -2.13076 -1.39414 1.56981 -0.190602) 2 (MaxTime 20.0) (CollisionThreshold 0.01) 3 (Tolerance 0.001) (SpeedFactor 0.5) (AccelerationFactor 1.0) 4 (CachePath "path" 0.005) 5 (CacheSamplingData "seed" "num_samples") 6 ) ## Find Joint Solution from an End Effector Set Placement Given placements of an end effector set, try to find a joint solution. This command is handled by EcMotionScriptFindSolution. Command format: 1 (find_solution <manip_id> <ee_set_id> <solution_symbol> 2 (<target_place_0> [<target_place_1> ...]) 3 [(<param0_name> <param0_value>) ...]) The command will try to find a joint solution for a manipulator (<manip_id>), given the target placement (<target_place_0>...) of an end effector set (<ee_set_id>). If a feasible joint solution is found, save the result to the solution real vector symbol (<solution_symbol>); otherwise, the real vector symbol will contain a 0-sized vector. A placement should be a mix of pose and real vector variables inside a pair of parentheses. Example command 1: 1 (motion_seq 2 (def_real_vec rv0 ()) 3 4 (find_solution 0 1 rv0 5 ((-1.4 -0.4 -2.1 -1.4 1.6 -0.2) 6 ((2.0 0.3 -0.8) (1 0 0 0)) 7 ) 8 ) 9 ) Example command 1 shows a script that tries to find a joint solution for manipulator 0. The target placement is for end effector set 1, and it is a mix of real vector and pose, corresponding to the definition of the end effector set. If a feasible joint solution is found, the result will be stored in symbol 'rv0'. List of Parameters. Parameter Name Description Default Value CollisionThreshold Collision threshold in work space in meters. 0.001 AttachPlacement End effector set placement at attachment. N/A AttachExclusion A vector of manipulator indexes, each pair of which is excluded from collision checking at attachment. N/A Several parameters can be set to further control the solution finding process. These parameters are optional; if the collision threshold is absent, the default value will be used. As shown in the command format, the parameters have to be at the end, but the order within is flexible. Example command 2: 1 (motion_seq 2 (def_real_vec rv0 ()) 3 (def_pose approach ((0 0 -0.01)(1 0 0 0))) 4 (def_pose attach ((0 0 0.01)(1 0 0 0))) 5 (def_pose part (get_frame 6 BASE)) 6 7 (find_solution 0 1 rv0 ((* part approach)) 8 (AttachPlacement ((* part attach))) 9 (AttachExclusion (1 6)) 10 ) 11 ) Example command 2 shows a script that tries to find a joint solution for manipulator 0, given placements of end effector set 1. The target placement is at the 'approach' pose, which is 0.01m backward along the 'part' base frame's z axis. The command also need validate that the 'attach' pose, which is 0.01m forward along the 'part' base frame's z axis, is reachable. The 'AttachExclusion' gives a set of manipulators, each pair of which is excluded from collision checking during the 'attach' validation. If this 'attach' pose is not reachable, the command will return failed. ## Disable Joint Limits Disable the enforcement of joint limits on a manipulator. This command is handled by EcManipulatorMotionDisableJointlimits. Command format: 1 (disable_joint_limits <manip_id:u32>) 2 (enable_joint_limits <manip_id:u32>) The command will fail if <manip_id> is invalid or if it failed to set the limits to disabled. Example format: 1 (enable_joint_limits 0) The command enables manipulator 0's joint limits. Example format: 1 (disable_joint_limits 0) The command disables manipulator 0's joint limits. # Container ## Motion Script Sequence A motion script sequence is a vector of motion scripts that run sequentially. This command is handled by EcMotionScriptSequence. Command format: 1 (motion_seq <motion_script> [<motion_script>] ...) Example format: See Find Joint Solution from an End Effector Set Placement. ## Motion Script Parallel A motion script parallel is a vector of motion scripts that run parallelly. Note that motion_para can be included in motion_seq and vice versa to achieve complex logic. This command is handled by EcMotionScriptParallel. Command format: 1 (motion_para <motion_script> [<motion_script>] ...) Example format: 1 (motion_para 2 (move_joint 0 (0 0 90deg 0 0 0) 1.0 0.001) 3 (move_joint 1 (0 0 0 90deg 0 0) 1.0 0.001) 4 ) This command moves manipulator 0 and manipulator 1 simultaneously. ## Function See Define Function. ## while See while. # Variable Definition, Assignment, Assertion and Print The following commands can define variables of supported types. They can ONLY be used within a container. The name of a variable must start with a letter or '_', and consist of only letters, numbers, and '_', and cannot be the same as any built-in motion script commands. A variable is only visible after its definition and within its container, and cannot be defined twice. ## Define Boolean Command format: 1 (def_bool <var_name> <bool>) Example: 1 (motion_seq 2 (def_bool a TRUE) 3 (def_bool b FALSE) 4 ) ## Define U32 Command format: 1 (def_u32 <var_name> <u32>) Example: 1 (motion_seq 2 (def_u32 a 0) 3 (def_u32 b BASE) 4 (def_u32 c 0x2) 5 (def_u32 d VOID) 6 ) Note BASE is a built-in U32 constant that equals to EcFoundCommon::BASEINDEX. VOID is a build-in U32 constant that equals to EcFoundCommon::VOIDINDEX. ## Define U32 Vector Command format: 1 (def_u32_vec <var_name> <u32_vec>) Example: 1 (motion_seq 2 (def_u32_vec a (BASE 0 1 2 3 4 5)) 3 ) To get a single element of the vector: Command format: 1 (elem_of <vec_name> <elem_index>) Example: 1 (motion_seq 2 (def_u32_vec a (0 1 2 3)) 3 (def_u32 elem2 (elem_of a 2)) 4 ) This will return false if the index is out of range or if <vec_name> is not a U32 Vector. To set a single element value of the vector: Command format: 1 (set_elem_of <vec_name> <elem_index> <u32>) Example: 1 (motion_seq 2 (def_u32_vec a (0 1 2 3)) 3 (set_elem_of a 2 5) 4 ) This will return false if the index is out of range or if <vec_name> is not a U32 Vector or if the value is not u32. ## Define Real Command format: 1 (def_real <var_name> <real>) All units can be used when defining a real value. Example: 1 (motion_seq 2 (def_real a 1.0) 3 (def_real b 1e-3) 4 (def_real c 2mm) 5 (def_real d 90deg) 6 ) ## Define Real Vector Command format: 1 (def_real_vec <var_name> <real_vec>) When using real literal, all units are allowed and can be mixed. Literals and variables can be mixed together. Example: 1 (motion_seq 2 (def_real_vec a (0.1 0.2m 0.3mm 0.4in 0.5rad 0.6deg)) 3 (def_real b 1) 4 (def_real_vec c (0 b)) 5 ) To get a single element of the vector: Command format: 1 (elem_of <vec_name> <elem_index>) Example: 1 (motion_seq 2 (def_real_vec a (0.1 0.2m 0.3mm 0.4in 0.5rad 0.6deg)) 3 (def_real elem2 (elem_of a 2)) 4 ) This will return false if the index is out of range or if the <vec_name> is not a Real Vector. To set a single element value of the vector: Command format: 1 (set_elem_of <vec_name> <elem_index> <real>) Example: 1 (motion_seq 2 (def_real_vec a (0.1 0.2m 0.3mm 0.4in 0.5rad 0.6deg)) 3 (set_elem_of a 2 5.0) 4 ) This will return false if the index is out of range or if <vec_name> is not a real Vector or if the value is not real. ## Define Translation Command format: 1 (def_trans <var_name> <translation>) When using real literal, only length units (meter, millimeter, inch) are allowed. Literals and variables can be mixed together. Example: 1 (motion_seq 2 (def_trans a (0.0m 1.0mm 2.0in)) 3 (def_real b 1mm) 4 (def_trans c (b 2mm 3mm)) 5 ) To get a single element of the translation: Command format: 1 (elem_of <trans_name> <elem_index>) Example: 1 (motion_seq 2 (def_trans a (0.0m 1.0m 2.0in)) 3 (def_real b 1mm) 4 (def_trans c (b (elem_of a 1) (elem_of a 2))) 5 ) This will return false if the index is out of range or if the <trans_name> is not a Translation. To set a single element value of the translation: Command format: 1 (set_elem_of <trans_name> <elem_index> <real>) Example: 1 (motion_seq 2 (def_trans a (0.0m 1.0m 2.0in)) 3 (set_elem_of a 2 5.0in) 4 ) This will return false if the index is out of range or if <trans_name> is not a Translation ## Define Orientation (Rotation) Command format: 1 (def_rot <var_name> <rotation>) A rotation literal is a list of rotation type (can be omitted if using quaternion) and 3 or 4 values. Literals and variables can be mixed together. The following rotation types are supported: • Quaternion (QUAT): This is the default type and can be omitted. 4 real values are required. No units are allowed. • Angle-Axis (AA): use EcOrientation::setFromAngleAxis. 3 real values are required. The 3 real values are treated as a 3D vector. The angle is calculated from the magnitude of the vector. The axis is the direction of the vector. Only angles units are allowed. • Roll-Pitch-Yaw (RPY): use EcOrientation::setFrom123Euler. 3 real values are required. Only angles units are allowed. • Yaw-Pitch-Roll (YPR): use EcOrientation::setFrom321Euler. 3 real values are required. Only angles units are allowed. • Direction-Cosine Columns (DCC): use EcOrientation::setFromDcmColumns. 3 3D vectors are required. They should be unit vectors, and form a right-handed frame, just like the columns of a rotation matrix. • Direction-Cosine Rows (DCR): use EcOrientation::setFromDcmRows. 3 3D vectors are required. They should be unit vectors, and form a right-handed frame, just like the rows of a rotation matrix. Example: 1 (motion_seq 2 (def_rot a (1 0 0 0)) 3 (def_rot b (QUAT 1 0 0 0)) 4 (def_rot c (AA 90deg 0 0)) 5 (def_rot d (RPY 90deg 0 0)) 6 (def_rot e (YPR 90deg 0 0)) 7 (def_real f 1deg) 8 (def_rot g (f 2 3)) 9 (def_rot h (DCC (1 0 0) (0 0 1) (0 -1 0))) 10 (def_rot i (DCR (1 0 0) (0 0 1) (0 -1 0))) 11 ) ## Define Pose Command format: 1 (def_pose <var_name> <pose>) Example: 1 (motion_seq 2 (def_pose a ((1 2 3) (1 0 0 0))) 3 (def_trans v0 (0.788 -0.032 0.034)) 4 (def_rot r0 (0 0 105)) 5 (def_pose p0 (v0 r0)) 6 ) ## Define String Command format: 1 (def_string <var_name> <string>) A string literal must be wrapped in "". Escape character is supported. Example: 1 (motion_seq 2 (def_string a "A") 3 (def_string b "\"B\"") 4 ) ## Assign New Value Once a variable is defined, it can be assigned a new value. The new value must be of the same type of the variable. Or there will be a parse error. Command format: 1 (:= <var_name> <new_value>) Example format: 1 (motion_seq 2 (def_u32 a 0) 3 (:= a 1) 4 ) This command changes the value of variable a to 1. ## Assert This command asserts whether the <statement> is true. It succeeds, only when the arguments are valid and the statement is true. When the assertion fails, a warning message will be printed if the <printWhenFail> flag is true. The default value of <printWhenFail> is true. Command format: 1 (assert <statement:bool> [<printWhenFail:bool>]) Example format: 1 (assert TRUE FALSE) This command asserts true but not print. ## Print Variables The print script can print any number of variables to the console window. "\n" will be printed automatically at the end of each print. Command format: 1 (print <variable> [<variable>...]) Example command: 1 (motion_seq 2 (def_bool b TRUE) 3 (def_trans t (0 1 2)) 4 (print "b = " b) 5 (print "t = " t) 6 ) If a console window is open, the output should be: Console window output of printing variables. # Data Storage The first two sections include commands can store/lookup different kinds of variables in/from the data map. And the commands in the third section are used to get/set digital inputs/outputs. ## Store(Set) Variables ### Set Boolean to Data Map Command format: 1 (set_data_map_bool <key:string> <value:bool>) Example command: 1 (set_data_map_bool "b0" TRUE) This command will store a bool variable named "b0" to the data map, with a value of TRUE. ### Set Orientation to Data Map Command format: 1 (set_data_map_rot <key:string> <value:rot>) Example format: 1 (set_data_map_rot "rot" (1 0 0 0))) This command sets a unit quaternion in rotation data map with key value as "rot". ### Set Pose to Data Map Command format: 1 (set_data_map_pose <key:string> <value:pose>) Example format: 1 (set_data_map_pose "pose" ((1 2 3)(0 1 0 0))) This command sets a pose in pose data map with key value as "pose". ### Set Real to Data Map Command format: 1 (set_data_map_real <key:string> <value:real>) Example format: 1 (set_data_map_real "a" 1.0) This command sets a real value 1 in real data map with key value as "a". ### Set Real Vector to Data Map Command format: 1 (set_data_map_real_vec <key:string> <value:real_vec>) Example format: 1 (set_data_map_real_vec "a" (1.0 1.0 1.0)) This command sets a real vector (1.0 1.0 1.0) in real vector data map with key value as "a". ### Set String to Data Map Command format: 1 (set_data_map_string <key:string> <value:string>) Example format: 1 (set_data_map_string "sam" "name") This command sets a string "name"in string data map with key value as "sam". ### Set Translation to Data Map Command format: 1 (set_data_map_trans <key:string> <value:trans>) Example format: 1 (set_data_map_trans "trans" (1 2 3))) This command sets a translation (1 2 3) in translation data map with key value as "trans". ### Set U32 to Data Map Command format: 1 (set_data_map_u32 <key:string> <value:u32>) Example format: 1 (set_data_map_u32 "a" 1) This command sets an integer value 1 in u32 data map with key value as "a". ### Set U32 Vector to Data Map Command format: 1 (set_data_map_u32_vec <key:string> <value:u32_vec>) Example format: 1 (set_data_map_u32_vec "a" (1 1 1)) This command sets an integer vector (1 1 1) in u32 vector data map with key value as "a". ## Lookup(Get) Variables ### Get Boolean from Data Map Command format: 1 (get_data_map_bool <key:string>) This command is used to get a boolean from the data map by <key>. Example command: 1 (motion_seq 2 (def_bool b0 (get_data_map_bool "b0")) 3 ) This command gets the boolean named "b0" from data map; This command will fail, if the named boolean does not exist. ### Get Orientation from Data Map Command format: 1 (get_data_map_rot <key:string>) This command is used to get an orientation from the data map by <key>. Example command: 1 (motion_seq 2 (def_rot rot (get_data_map_rot "rot")) 3 ) This command gets the rotation named "rot" from data map; This command will fail, if the named rotation does not exist. ### Get Pose from Data Map Command format: 1 (get_data_map_pose <key:string>) This command is used to get a pose from the data map by <key>. Example command: 1 (motion_seq 2 (def_pose p (get_data_map_pose "p")) 3 ) This command gets the pose named "p" from data map; This command will fail, if the named pose does not exist. ### Get Real from Data Map Command format: 1 (get_data_map_real <key:string>) This command is used to get a real from the data map by <key>. Example command: 1 (motion_seq 2 (def_real r (get_data_map_real "r")) 3 ) This command gets the real value named "r" from data map; This command will fail, if the named real value does not exist. ### Get Real Vector from Data Map Command format: 1 (get_data_map_real_vec <key:string>) This command is used to get a real vector from the data map by <key>. Example command: 1 (motion_seq 2 (def_real_vec rvec (get_data_map_real_vec "rvec")) 3 ) This command gets the real vector named "rvec" from data map; This command will fail, if the named real vector does not exist. ### Get String from Data Map Command format: 1 (get_data_map_string <key:string>) This command is used to get a string from the data map by <key>. Example command: 1 (motion_seq 2 (def_string s (get_data_map_string "s")) 3 ) This command gets the string named "s" from data map; This command will fail, if the named string does not exist. ### Get Translation from Data Map Command format: 1 (get_data_map_trans <key:string>) This command is used to get a translation from the data map by <key>. Example command: 1 (motion_seq 2 (def_trans t (get_data_map_trans "t")) 3 ) This command gets the translation named "t" from data map; This command will fail, if the named translation does not exist. ### Get U32 from Data Map Command format: 1 (get_data_map_u32 <key:string>) This command is used to get a u32 from the data map by <key>. Example command: 1 (motion_seq 2 (def_u32 a (get_data_map_u32 "a")) 3 ) This command gets the integer value named "a" from data map; This command will fail, if the named integer value does not exist. ### Get U32 Vector from Data Map Command format: 1 (get_data_map_u32_vec <key:string>) This command is used to get a u32 vector from the data map by <key>. Example command: 1 (motion_seq 2 (def_u32_vec intVec (get_data_map_u32_vec "intVec")) 3 ) This command gets the integer vector named "intVec" from data map; This command will fail, if the named integer vector does not exist. ## Digital Inputs/Outputs ### Set Digital Output Command format 1: 1 (set_digital_output <board_id:u32> <value:u32>) Example format 1: 1 (set_digital_output 0 1) This command sets board id 0 to 1. Command format 2: 1 (set_digital_output <board_id:u32> <channel_id:u32> <value:bool>) Example format 2: 1 (set_digital_output 0 1 TRUE) This command sets board id 0 to channel id 1 with TRUE. ### Get Digital Input Command format: 1 (get_digital_input <board_id:u32> <port_id:u32>) Example command: 1 (motion_seq 2 (def_bool b_0_31 (get_digital_input 0 31)) 3 ) This script will create a boolean variable b_0_31 with initial value the digital input of Board 0 Port 31. # Type-Specific Script The following commands can only be used where certain type is expected and cannot be used stand-alone. ## Boolean ### Get Boolean from Data Map Please see Get Boolean from Data Map ### Get Digital Input Please see Get Digital Input. ### Get Hit Joint Limit Flag This script gets the hit joint limit flag given the manipulator index. If any joint of the manipulator hits joint limit, this script will return TRUE. Command format: 1 (hit_joint_limit <manip_id>) ### Check Collision This script checks collision of the world, or check collision of a specific manipulator with the world, if the manipulator index is provided. If a collision (which is not excluded) is detected, this script will return TRUE, and a pair of links that are detected in collision will be stored in the result. In such cases, the results will be in format: (manip_index1 link_index1 manip_index2 link_index2). If no collision is detected, the scrip will return FALSE, and the results will be empty. Command format: 1 (check_collision [<manip_id:u32>] <tolerance:real> <results:u32_vec>) ### Comparison Operators #### Equals: == Command format: 1 (== <var_u32> <var_u32>) Note This command only supports U32 variables, for now. #### Approximate Equals: ~= Command format: 1 (~= <var1> <var2> <tol:real>) where <var1> and <var2> must be of the same type and can be real, translation, orientation, pose, or real vector variables. The <tol> value is the tolerance to consider equal in floating comparison. #### Not Equal: != Command format: 1 (!= <var_u32> <var_u32>) Note This command only supports U32 variables, for now. #### Less Than: <, Less Than or Equal: <=, Greater Than: >, Greater Than or Equal: >= Command format: 1 (< <var1> <var1>) where <var1> and <var2> can be U32 or real variables as long as both are the same type. Note If using a real or U32 value, attention must be paid to the casting of a U32 to a real: 1 (def_bool a (< 1 1.0)) # Will fail because it cannot cast a real (1.0) to be a U32 (1) 2 (def_bool b (< 1.0 1)) # Will succeed and compare because it can cast a U32 (1) to a real (1.0) 3 # Use explicit defs to avoid casting 4 (def_real r 1.0) 5 (def_u32 u 1) 6 (def_bool c (< r u)) # Will fail and avoid casting The operations <=, >, >= follow the same as above just using their respective operation symbol. ### Logic Operators #### Logic AND: && Command format: 1 (&& <var_bool> <var_bool> [<var_bool> ...]) Example command: 1 (motion_seq 2 (def_bool b0 (&& (< 1 2) (< 3 2) (get_digital_input 0 31))) 3 ) After running this script, b0 will be FALSE. Also since (< 3 2) is false, the third command get_digital_input will not be evaluated. #### Logic OR: || Command format: 1 (|| <var_bool> <var_bool> [<var_bool> ...]) #### Logic NOT: ! Command format: 1 (! <var_bool>) ## Orientation ### Get Orientation from Data Map Please see Get Orientation from Data Map ### Get Orientation from Pose Command format: 1 (get_rot <var_pose>) This command is used to extract the orientation part from a pose variable. ### Transformation Command format: 1 (* <var_rot> <var_rot> [<var_rot> ...]) This command multiplies the orientations in the argument list. ### Inverse Command format: 1 (inv <var_rot>) This command calculate the inverse of the given orientation. ## Pose ### Get Pose from Data Map Please see Get Pose from Data Map ### Get Frame This command can be used to get the primary frame or a named frame from any link of a manipulator or a named frame from the EcManipulatorSystem in the world frame. To get a named frame from the EcManipulatorSystem: 1 (get_frame <frame_name>) Example command: 1 (motion_seq 2 (def_pose p0 (get_frame "p0")) 3 ) This command gets the named frame "p0" from EcManipulatorSystem. If the named frame does not exist, it will return failed. To get the primary frame of a link of a manipulator: 1 (get_frame <manip_id> <link_id>) The <link_id> is the index of the link. For the base link, use BASE. Example command: 1 (motion_seq 2 (def_pose p0 (get_frame 0 BASE)) 3 ) This command gets the primary frame of the base link of Manipulator 0. If the manipulator index or the link index does not exist, it will return failed. To get a named frame from a link of a manipulator: 1 (get_frame <manip_id> <link_id> <frame_name>) Example command: 1 (motion_seq 2 (def_pose p0 (get_frame 0 5 "tool_attachment")) 3 ) This command gets the named frame "tool_attachment" from Link 5 of Manipulator 0. If the manipulator index or the link index or the named frame does not exist, it will return failed. ### Set Named Frame This command can be used to set a named frame from any link of a manipulator or a named frame of the EcManipulatorSystem in the world frame. If the named frame does not exist, it will add a new named frame with the given offset. To set a named frame from the EcManipulatorSystem: 1 (set_named_frame <frame_name> <frame_offset>) Example command: 1 (motion_seq 2 (def_pose offset ((1 0 0) (1 0 0 0))) 3 (set_named_frame "frame0" offset) 4 ) This command will set the named frame "frame0" from EcManipulatorSystem with the given offset. To set a named frame from a link of a manipulator: 1 (set_named_frame <manip_id> <link_id> <frame_name> <frame_offset>) Example command: 1 (motion_seq 2 (def_pose offset ((1 0 0) (1 0 0 0))) 3 (set_named_frame 0 5 "tool_attachment" offset) 4 ) This command will set the named frame "tool_attachment" of Link 5 of Manipulator 0 to the given offset. If the manipulator index or the link index, it will return failed. ### Inverse Command format: 1 (inv <var_pose>) This is command inverts <var_pose>. ### Transformation Command format: 1 (* <var_pose> <var_pose> [<var_pose> ...]) This command multiplies the poses in the argument list which is equivalent to pose transformation. Example command: 1 (motion_seq 2 (def_pose p0 (get_frame 0 "")) 3 (def_pose p1 (get_frame 1 "")) 4 (def_pose p2 (* (inv p0) p1)) 5 ) This command gets the base primary frame of Robot 0 in the world frame to p0 and the base primary frame of Robot 1 in the world frame to p1. It then calculates $$p2 = p0 ^ {-1} p1$$ which is the base primary frame of Robot 1 in the base primary frame of Robot 0 and stores it to p2. ### Get End Effector Pose Command format: 1 (get_ee_pose <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>]) This command is used to get the current translation and orientation of an end effector of manipulator <manip_id>. If <ee_set_id> and <ee_id> are not provided, the first end effector of the current active end effector set is used. If the <manip_id>, <ee_set_id>, or <ee_id> do not exist, the command will return failed. ## Real ### Get Real from Data Map Please see Get Real from Data Map. ### Dot Product of Translations Command format: 1 (dot <var_trans> <var_trans>) This command is used to calculate the dot product between two translation variables. ### Get State Time Command format: 1 (def_real <var_name> (get_state_time)) This command is used to calculate L1 norm/L2 norm/LInf norm of real value, translation and real vector. ### Norm Command format: 1 (norm [<norm_mode>] <variable>) This command returns the norm of the variable. The variable can be real, real vector, or translation. <norm_mode> can be 1 (L1 norm), 2 (L2 norm), INF (infinity norm). If not provided, the command calculates L2 norm. Example format: 1 (motion_seq 2 (def_real a 1) 3 (def_trans t (1 -1 -1)) 4 (def_real_vec rvec (1.0 -1.0 1.0 -1.0)) 5 # an1 = 1 6 (def_real an1 (norm 1 a)) 7 # an2 = 1 8 (def_real an2 (norm a)) 9 # an2 = 1 10 (:= an2 (norm 2 a)) 11 # anInf = 1 12 (def_real anInf (norm INF a)) 13 # tn1 = 3 14 (def_real tn1 (norm 1 t)) 15 # tn2 = sqrt(3) 16 (def_real tn2 (norm t)) 17 # tnInf = 1 18 (def_real tnInf (norm INF t)) 19 # rn1 = 4 20 (def_real rn1 (norm 1 rvec)) 21 # rn2 = 2 22 (def_real rn2 (norm rvec)) 23 # rnInf = 1 24 (def_real rnInf (norm INF rvec)) 25 ) ## Real Vector ### Get Real Vector from Data Map Please see Get Real Vector from Data Map ### Get Current Joint Positions Command format: 1 (get_joint_positions <manip_id:u32>) This command is used to get the current positions of all joints of manipulator <manip_id>. Example command: 1 (motion_seq 2 (def_real_vec rv0 (get_joint_positions 5)) 3 ) This command gets the positions of all joints of manipulator 5; This command will fail, if manipulator 5 does not exist. ### Get Current Joint Velocities Command format: 1 (get_joint_velocities <manip_id:u32>) This command is used to get the current velocities of all joints of manipulator <manip_id>. Example command: 1 (motion_seq 2 (def_real_vec rv0 (get_joint_velocities 5)) 3 ) This command gets the velocities of all joints of manipulator 5; This command will fail, if manipulator 5 does not exist. ### Get Current Joint End Effector Command format: 1 (get_joint_ee <manip_id>) This command is used to get the current positions of only the active joints of manipulator <manip_id>. This is the same as get_joint_positions above if all joints are active. However, if the robot has passive joints, then this will return different results than get_joint_positions. The size of the vector returned by get_joint_ee will never exceed that returned by get_joint_positions. For example, a delta robot may be modeled as a 15-joint robot but with only 3 active joints. Then get_joint_ee will return a vector of size 3 while get_joint_positions size 15. Example command: 1 (motion_seq 2 (def_real_vec rv0 (get_joint_ee 5)) 3 ) This command gets the positions of the active joints of manipulator 5; This command will fail, if manipulator 5 does not exist. ### Get Current Joint End Effector Velocity Command format: 1 (get_joint_ee_velocity <manip_id>) Similar to get_joint_ee above, this command is used to get the current velocities of only the active joints of manipulator <manip_id>. Example command: 1 (motion_seq 2 (def_real_vec rv0 (get_joint_ee_velocity 5)) 3 ) This command gets the velocities of the active joints of manipulator 5; This command will fail, if manipulator 5 does not exist. ## String ### Get String from Data Map Please see Get String from Data Map ## Translation ### Get Translation from Data Map Please see Get Translation from Data Map ### Get Translation from Pose Command format: 1 (get_trans <var_pose>) This command is used to extract the translation part from a pose variable. Example format: 1 (motion_seq (def_trans tTrans (get_trans ((1 2 3) (0 0 0))))) This command extracts the translation part from a pose variable, so that a translation variable named tTrans will be defined as (1 2 3). ### Multiplication of Translation Command format for scalar multiplication: 1 (* <var_real> <var_trans>) Command format for orientation multiplication: 1 (* <var_rot> <var_trans>) Command format for pose multiplication: 1 (* <var_pose> <var_trans>) This command is used to calculate multiplication between a real (or rotation, or pose) variable and a translation variable. Example format: 1 (motion_seq 2 (def_trans t (1 0 0)) 3 # t2 = 2*t 4 (def_trans t2 (* 2 t)) 5 # t3 = R*t 6 (def_rot R (0 0 45deg)) 7 (def_trans t3 (* R t)) 8 # t4 = P*t 9 (def_pose P (0 1 0)(-90deg 0 0)) 10 (def_trans t4 (* P t)) 11 ) ### Cross Product of Translation Command format: 1 (cross <var_trans> <var_trans> [<var_trans> ...]) This command is used to calculate the cross product of multiple translation variables. Example format: 1 (motion_seq 2 # define a X vector 3 (def_trans X (1 0 0)) 4 # define a Y vector 5 (def_trans Y (0 1 0)) 6 # Z = X x Y 7 (def_trans Z (cross X Y)) 8 ) Note Only the real vector with a size of 3 can be converted into a translation. ## U32 ### Get U32 from Data Map Please see Get U32 from Data Map ### Get Manipulator Index Command format: 1 (get_manip_id <manip_label:string>) This command is used to get manipulator index by <manip_label>. Example command: 1 (motion_seq 2 (def_u32 u0 (get_manip_id "primary_arm_right") 3 ) If the manipulator named "primary_arm_right" exists, u0 will be its index; otherwise returns failed. ### Get Link Index Command format 1: 1 (get_link_id <manip_id:u32> <link_label:string>) Command format 2: 1 (get_link_id <manip_label:string> <link_label:string>) This command is used to get link index by <manip_id>/<manip_label> and <link_label>. Example command: 1 (motion_seq 2 (def_u32 u0 (get_link_id 0 "wrist") 3 (def_u32 u1 (get_link_id "primary_arm_right" "wrist") 4 ) If the manipulator 0 exists, and the link of this manipulator named "wrist" exists, u0 will be the link's index; otherwise returns failed. If the manipulator named "primary_arm_right" exists, and the link of this manipulator named "wrist" exists, u1 will be the link's index; otherwise returns failed. ### Get Size of a Vector Command format 1: 1 (size_of <var_real_vec>) Example format 1: 1 (motion_seq 2 (def_real_vec rvec (1.0 2.0 3.0)) 3 (def_u32 rlength (size_of rvec)) Command format 2: 1 (size_of <var_u32_vec>) Example format 2: 1 (motion_seq 2 (def_u32_vec uvec (1 2 3)) 3 (def_u32 ulength (size_of uvec)) This command is used to get the size of a <var_real_vec> or <var_u32_vec>. ### Bitwise Operators #### Bitwise AND: & Command format: 1 (& <var_0:u32> <var_1:u32> [<var_2:u32> ...]) Example command: 1 (motion_seq 2 (def_u32 u0 (& 2 15 7)) 3 ) After running this script, u0 will be 2. #### Bitwise OR: | Command format: 1 (| <var_0:u32> <var_1:u32> [<var_2:u32> ...]) Example command: 1 (motion_seq 2 (def_u32 u0 (| 2 11 5)) 3 ) After running this script, u0 will be 15. #### Bitwise XOR: ^ Command format: 1 (^ <var_0:u32> <var_1:u32>) Example command: 1 (motion_seq 2 (def_u32 u0 (^ 2 7)) 3 ) After running this script, u0 will be 5. ## U32 Vector ### Get U32 Vector from Data Map Please see Get U32 Vector from Data Map ## Arithmetic Operators ### Add: + Command format: 1 (+ <var_0> <var_1> [<var_2> ...]) Note This command now supports Real, Translation, U32, Real Vector, and U32 Vector variables. Vectors must all be the same size or the command will fail. Example command: 1 (motion_seq 2 (def_bool b0 (< (+ 1 1) 2)) 3 ) After running this script, b0 will be FALSE. ### Subtract: - Command format: 1 (- <var_0> [<var_1> ...]) Note If only <var_0> is available, the subtraction is the same as the negate operation. This command now supports Real, Translation, U32, Real Vector, and U32 Vector variables. Vectors must all be the same size or the command will fail. Example: 1 (motion_seq 2 (def_real a (- 10)) # a == -10 3 (def_real b (- 10 1 2 3 4)) # b == 0 4 ) ### Multiply: * Command format: 1 (* <var_0> <var_1> [<var_2> ...]) Note This command only supports Real and U32 variables. Please refer to vector variable for multiplication operation of translation variables. Example format: 1 (motion_seq 2 (def_real a 1) 3 (def_real b (* a 2) 4 ) ### Divide: / Command format: 1 (/ <var_0> [<var_1> ...]) Note If only <var_0> is available, the division is an inversion. This command only supports Real variables. Example: 1 (motion_seq 2 (def_real a (/ 4.0)) # a == 0.25 3 (def_real b (/ 6 2 3)) # b == 1 4 ) # Define Function def_fun defines a function in a container. Command format: 1 (def_fun <function_name> ([parameter_list]) 2 [function_body] 3 ) The requirement of function name is the same as variable name (Section Define Variable). [parameter_list] is a list of variable declarations without value. function_body is a list of motion scripts. Pass-by-reference is supported by prepending & to the variable name (no space in-between). The argument passed by reference must be a symbol. A function is a container. Therefore, local variables and functions can be defined inside a function. Recursion is not allowed. Example: 1 (motion_seq 2 # foo: a = b + 1 3 (def_fun foo ((def_u32 &a) (def_u32 b)) 4 # foo1: x = x + 1 5 (def_fun foo1 ((def_u32 &x)) 6 (def_u32 c 1) 7 (:= x (+ x c)) 8 ) 9 (foo1 b) 10 # a = b 11 (:= a b) 12 ) 13 (def_u32 a 0) 14 (foo a 1) 15 ) Variable a is passed to foo by reference. The literal 1 is passed to foo by value. After calling foo, the value of Variable a will be 2. # Control Logic ## if The if command will check the condition first, and if it is true, it will run <motion_script>. Otherwise, it will run <else_motion_script> if it is provided. Command format: 1 (if <condition> 2 <motion_script> 3 [<else_motion_script>] 4 ) Example command: 1 (if (get_digital_input 0 31) 2 (move_joint 0 (0 0 90deg 0 0 0) 1.0 0.001) 3 (move_joint 0 (0 0 0 0 0 0) 1.0 0.001) 4 ) This script will check digital input Board 0, Port 31. If it is high, move the joints to (0 0 90deg 0 0 0), otherwise, move the joints to (0 0 0 0 0 0). ## while The while command starts a while-loop by checking the condition first, and if it is true, it will run <motion_script>, and then start another loop until the condition is false. Command format: 1 (while <condition> 2 <motion_script> 3 ) Example command: 1 (motion_seq 2 (def_u32 ii 0) 3 (while (< ii 10) 4 (motion_seq 5 (move_joint 0 (0 0 90deg 0 0 0) 1.0 0.001) 6 (move_joint 0 (0 0 0 0 0 0) 1.0 0.001) 7 (:= ii (+ ii 1)) 8 ) 9 ) 10 ) This script will move the joints to (0 0 90deg 0 0 0) then to (0 0 0 0 0 0) and repeat the motion for 10 times. ## wait Command format: 1 (wait <time:real>) This command is used to suspend motion script for <time> seconds. If <time> is less than or equal to 0, the motion script will not be suspended. Command format: 1 (motion_seq 2 (wait 1.0) 3 ) This command suspends motion script for 1.0 seconds. ## return This command is used to return from all containers up to the first function (a function is a container). Command format: 1 (return) Example command: 1 (motion_seq 2 (def_fun foo ((def_u32 a)) 3 (if (== a 0) 4 (motion_seq 5 (return) 6 ) 7 ) 8 (print "a = " a) 9 ) 10 (foo 0) 11 (foo 1) 12 ) This script will only print "a = 1". ## break This command is used to break from while loop. Command format: 1 (break) Example command: 1 (while TRUE 2 (def_u32 a 0) 3 (print "before break") 4 (if (== a 0) 5 (break) 6 ) 7 (print "after break") 8 ) This script will only print "before break". # Include This command allows users to include pre-written EcScript (.ecs) file into current EcScript contexts. Environment variables are supported, which must be wrapped in{}.

Command format:

1 (motion_seq
2  (include "filePath")
3 )
Note
This command can only be used within a container.

Example:

Suppose ${USER_DATA}/ecScript/preWrittenScript.ecs stores the following scripts: 1 (def_fun addFun ((def_u32 &a)) 2 (:= a (+ a 1)) 3 ) 4 (def_fun addFun2 ((def_u32 &a)) 5 (:= a (+ a 2)) 6 ) It can be used in: 1 (motion_seq 2 (include "${USER_DATA}/ecScript/preWrittenScript.ecs")
3  (def_u32 a 0)
6  (print a)
7 )

When users run this motion sequence, the preWrittenScript will be loaded into the example motion sequence. The console will print 3.

# Comment

Use # to lead a line of comment.

Example:

1 # A motion sequence
2 (motion_seq
3  # Home
4  (move_joint 0 (0 0 0 0 0 0) 1.0 0.001)
5  # Third joint goes to 30 deg
6  (move_joint 0 (0 0 30deg 0 0 0) 1.0 0.001)
7 )

# Custom Motion Scripts

It is possible to provide user-defined EcMotionScripts using EcMotionScriptObject::registerScript by passing in a creator function for a derived class of an EcMotionScript variable type.

Example:

Setting up the registration:

class ExampleCustomMotionScriptObject : public EcMotionScriptRealObject
{
public:
static EcMotionScriptRealObject* newObject()
{
return new ExampleCustomMotionScriptObject();
}
static const EcString& scriptToken()
{
static const EcString token = "my_token";
}
virtual const EcString& token () const EC_OVERRIDE
{
return scriptToken();
}
virtual EcBoolean read(const EcMotionScriptTokenTree& tokenTree, EcString* pErrorMsg) EC_OVERRIDE
{
return EcTrue;
}
virtual EcString write() const EC_OVERRIDE
{
return scriptToken();
}
virtual Status run(EcBaseControlSystemModifier& modifier, const EcReal currentTime) EC_OVERRIDE
{
return m_Status;
}
virtual void restart() EC_OVERRIDE
{
return;
}
};
// Registering it later, will return false if token is already registered or other error
EcMotionScriptRealObject::registerScript(ExampleCustomMotionScript::scriptToken(),
ecboost::bind(&ExampleCustomMotionScript::newObject));
// Should now return true if was registered already
EcBoolean result = EcMotionScriptRealObject::isKeyword(ExampleCustomMotionScript::scriptToken());