Actin®  Version 5.3.0 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.

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 (move_joint <manip_id:u32> [<ee_set_id:u32> <ee_id:u32>] <cmd_joints:real_vec> (<speed_factor:real> <acceleration_factor:real>) <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>. The command returns succeeded if the difference calculated by EcCoordinatedJointEndEffector::difference is smaller than <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 Pose

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

Command format:

1 (move_pose <manip_id:u32> <ee_set_id:u32> <ee_id:u32> <cmd_pose:pose> (<speed_factor:real> <acceleration_factor:real>) <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 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 (move_pose_rel <manip_id:u32> <ee_set_id:u32> <ee_id:u32> <delta_pose:_pose> (<speed_factor:real> <acceleration_factor:real>) <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.

Pose Sequence

Pose sequence moves the robot with a sequence of Cartesian space position commands of end effector. The pose sequence uses Bezier curves to blend between poses. This command is handled by EcEndEffectorMotionMovePoseSequence.

Command format:

1 (pose_seq <manip_id> <ee_set_id> <ee_id>
2  (move_pose ...) [(move_pose ...)] ...
3 )

The sequence is able to include more than one via poses. Via poses are added by appending move_pose commands.

Example command:

1 (pose_seq 0 1 0
2  (move_pose 0 1 0 ((0.1 -0.3 0.1) (0.0 0.0 90.0deg)) 0.3 0.03)
3  (move_pose 0 1 0 ((0.1 -0.4 0.1) (0.0 0.0 90.0deg)) 0.5 0.03)
4  (move_pose 0 1 0 ((0.0 -0.4 0.1) (0.0 0.0 90.0deg)) 0.5 0.03)
5  (move_pose 0 1 0 ((0.0 -0.3 0.1) (0.0 0.0 90.0deg)) 0.3 0.001)
6 )

This command moves the position of Robot 0 with a sequence of Cartesian space commands. It first use 30% speed to move it to (0.1m -0.3m 0.1m), Euler angles (0.0deg 0.0deg 90.0deg) with blending radius 0.03m, then use 50% speed to move it to (0.1m -0.4m 0.1m), then move it to (0.0m -0.4m 0.1m) and finally move it to (0.0m -0.3m 0.1m) with 0.001 tolerance.

On a Cyton Gamma-1500, the path looks like:

The path of a sample pose_seq command.

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 move_circular is used within interp_pose_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 Linear

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

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 move_linear is used within interp_pose_seq. If not provided, the blend radius is 0 by default.

Interpolated Pose Sequence

Interpolated pose sequence moves the TCP through a sequence of linear motions and circular motions with desired speed limits configured by speed factors. This command is handled by EcEndEffectorMotionInterpolatedPoseSequence. This command uses a look ahead algorithm to maximize the feedrate within speed and acceleration limits.

Command format:

1 (interp_pose_seq <manip_id> <ee_set_id> <ee_id>
2  [(move_linear ...)]
3  [(move_circular ...)]
4  ...
5 )

Example command:

1 (interp_pose_seq 0 1 0
2  (move_linear 0 1 0 ((-150mm 350mm 100mm)(-180deg 0 0)) 0.1)
3  (move_circular 0 1 0 (-150mm 400mm 100mm) (0 0 1) 90deg 0.1)
4  (move_linear 0 1 0 ((-100mm 500mm 100mm)(0 -90deg -180deg)) 0.1)
5  (move_circular 0 1 0 (-100mm 500mm 50mm) (1 0 0) -90deg 0.1)
6  (move_linear 0 1 0 ((-100mm 550mm 0mm)(0 -90deg -180deg)) 0.1)
7 )

On a UR5, the path looks like:

The path of a sample interp_pose_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_acd <manip_id> <acd_id>)

Example command:

1 (set_acd 0 1)

This command set 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_apcm <manip_id> <apcm_id>)

Example command:

1 (set_apcm 0 1)

This command set 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_bsp <manip_id> <speed_factor>)

Set Sensed State

Set the sensed state of a manipulator. This command is handled by EcManipulatorMotionSetSensedState.

Command format 1:

1 (set_sensed_state <manip_id> <base_pose> <joint_positions>)

Command format 2:

1 (set_sensed_state <manip_id> <base_pose>)

Command format 3:

1 (set_sensed_state <manip_id> <joint_positions>)

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:

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.

Exclude/Include Collision

To exclude/include collision check between a manipulator and everything else:

1 (exclude_collision/include_collision <manip_id_0>)

To exclude/include collision check between two manipulators:

1 (exclude_collision/include_collision <manip_id_0> <manip_id_1>)

To exclude/include collision check between a manipulator and links of another manipulator:

where, <link_indices> is a U32 vector.

To exclude/include collision check between a link of a manipulator and links of another manipulator:

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>)

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 the 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.

List of Parameters.
Parameter Name Description If Absent
MaxTime Maximum planning time in seconds. 5.0 (default value)
CollisionThreshold Collision threshold in work space in meters during planning. 0.001 (default value)
SpeedFactor Speed factor used in execution. 1.0 (default value)
Tolerance Tolerance used in execution. 0.001 (default value)
AccelerationFactor Acceleration factor used in execution. Acceleration factor won't be used.
CachePath Name of the cached path, and threshold for assertion. Path caching won't be used.

Extra note for path caching While the other 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 assertion_approx_eq 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, are smaller than this threshold.

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 )

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.

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>] ...)

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>] ...)

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 )
Note
BASE is a built-in U32 constant that equals to EcFoundCommon::BASEINDEX.

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.

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.

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.

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 real 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.

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 )

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>)

Assert Approximate Equal

This command asserts whether the Euclidean distance of two real vectors is smaller than the threshold. It succeeds, only when the two real vectors have the same dimension, and the Euclidean distance is smaller than the threshold.

Command format:

1 (assert_approx_eq <real_vec1> <real_vec2> <threshold>)

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 U32 to Data Map

Command format:

1 (set_dm_u32 <var_name> <var_u32>)

Example command:

1 (set_dm_u32 "u0" 100)

This command will store a u32 variable named "u0" to the data map, with a value of 100.

Set U32 Vector to Data Map

Command format:

1 (set_dm_u32_vec <var_name> <var_u32_vec>)

Set Real to Data Map

Command format:

1 (set_dm_real <var_name> <var_real>)

Set Real Vector to Data Map

Command format:

1 (set_dm_real_vec <var_name> <var_real_vec>)

Set String to Data Map

Command format:

1 (set_dm_string <var_name> <var_string>)

Lookup(Get) Variables

Get Real from Data Map

Please see Get Real from Data Map.

Get Real Vector from Data Map

Please see Get Real Vector from Data Map.

Get U32 from Data Map

Please see Get U32 from Data Map.

Get U32 Vector from Data Map

Please see Get U32 Vector from Data Map.

Get String from Data Map

Please see Get String from Data Map

Digital Inputs/Outputs

Set Digital Input

Command format:

1 (set_di <board_id> <var_u32>)

Set Digital Output

Command format 1:

1 (set_do <board_id> <var_u32>)

Command format 2:

1 (set_do <board_id> <channel_id> <var_bool>)

Type-Specific Script

The following commands can only be used where certain type is expected and cannot be used stand-alone.

Boolean

Get Digital Input

Command format:

1 (get_di <board_id> <port_id>)

Example command:

1 (motion_seq
2  (def_bool b_0_31 (get_di 0 31))
3 )

This script will create a boolean variable b_0_31 with initial value the digital input of Board 0 Port 31.

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> can be real, translation, or orientation variables as long as both are the same type. 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_di 0 31)))
3 )

After running this script, b0 will be FALSE. Also since (< 3 2) is false, the third command get_di will not be evaluated.

Logic OR: ||

Command format:

1 (|| <var_bool> <var_bool> [<var_bool> ...])

Command format:

1 (! <var_bool>)

Orientation

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 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 will get 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:

Example command:

1 (motion_seq
2  (def_pose p0 (get_frame 0 BASE))
3 )

This command will get 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:

Example command:

1 (motion_seq
2  (def_pose p0 (get_frame 0 5 "tool_attachment"))
3 )

This command will get 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.

Convert Real Vector to Pose

Command format:

1 (real_vec_to_pose <var_real_vec>)

This command is used to convert a real vector into a pose.

Note
Only the real vector with a size of 7 can be converted into a pose.

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

Command format:

1 (get_dm_real <var_name>)

This command is used to get a real from the data map by <var_name>.

Example command:

1 (motion_seq
2  (def_real r0 (get_dm_real "r0"))
3 )

This command will get the real named "r0" from data map; this will return failed, if the named real does not exist.

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.

Real Vector

Get Real Vector from Data Map

Command format:

1 (get_dm_real_vec <var_name>)

This command is used to get a real vector from the data map by <var_name>.

Example command:

1 (motion_seq
2  (def_real_vec rv0 (get_dm_real_vec "rv0"))
3 )

This command will get the real vector named "rv0" from data map; this will return failed, if the named real vector does not exist.

Get Current Joint Positions

Command format:

1 (get_joint_positions <manip_id>)

This command is used to get the current joint positions of manipulator <manip_id>.

Example command:

1 (motion_seq
2  (def_real_vec rv0 (get_joint_positions 5))
3 )

This command will get the joint positions of manipulator 5; this will return failed, if manipulator 5 does not exist.

Translation

Get Translation from Pose

Command format:

1 (get_trans <var_pose>)

This command is used to extract the translation part from a pose variable.

Convert Real Vector to Translation

Command format:

1 (real_vec_to_trans <var_real_vec>)

This command is used to convert <var_real_vec> into a translation variable.

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.

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.

Note
Only the real vector with a size of 3 can be converted into a translation.

U32

Get U32 from Data Map

Command format:

1 (get_dm_u32 <var_name>)

This command is used to get a u32 from the data map by <var_name>.

Get Manipulator Index

Command format:

1 (get_manip_id <manip_label>)

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 Size of a Vector

Command format 1:

1 (size_of <var_real_vec>)

Command format 2:

1 (size_of <var_u32_vec>)

This command is used to get the size of a <var_real_vec> or <var_u32_vec>.

Get U32 Vector from Data Map

Command format:

1 (get_dm_u32_vec <var_name>)

This command is used to get a u32 vector from the data map by <var_name>.

Example command:

1 (motion_seq
2  (def_u32_vec uv0 (get_dm_u32_vec "uv0"))
3 )

This command will get the U32 vector named "uv0" from data map; this will return failed, if the named real vector does not exist.

Get String from Data Map

Command format:

1 (get_dm_string <var_name>)

This command is used to get a string from the data map by <var_name>.

Example command:

1 (motion_seq
2  (def_string str0 (get_dm_u32_vec "str0"))
3 )

This command will get the string named "str0" from data map; this will return failed, if the named real vector does not exist.

Arithmetic Operators

Command format:

1 (+ <var_0> <var_1> [<var_2> ...])
Note
This command now supports Real, Translation and U32 variables.

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> available, the substraction is the same with negate operation. This command now supports Real, Translation and U32 variables.

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.

Divide: /

Command format:

1 (/ <var_0> [<var_1> ...])
Note
This command only supports Real variables.

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_di 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.

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(),
boost::bind(&ExampleCustomMotionScript::newObject));
// Should now return true if was registered already
EcBoolean result = EcMotionScriptRealObject::isKeyword(ExampleCustomMotionScript::scriptToken());
Created by Energid Technologies www.energid.com