Based on contributions by How-to, salvacmp.
Rotating the Doosan tool or head is done through the A, B, C rotation values of a Cartesian pose (posx). Rotating a large amount in one move can push a joint past its ±360° limit and trigger a servo lock error that requires manually unlocking the servo and restarting the robot. This article covers basic rotation and a helper function that sweeps through the rotation in steps to avoid that error.
What you need
- A Doosan robot
- A laptop with DRL Studio (Homberger Hub) installed
Steps
1. Understand the posx rotation values
posx(X=0, Y=0, Z=0, A=0, B=0, C=0)
| Input | Type | Description |
|---|---|---|
| X | float | X coordinate in mm |
| Y | float | Y coordinate in mm |
| Z | float | Z coordinate in mm |
| A | float | Rotation around the Z-axis, in degrees, world coordinates |
| B | float | Rotation around the Y-axis, in degrees, world coordinates |
| C | float | Rotation around the Z-axis, in degrees, world coordinates |
By default the head points up.
2. Rotate the head to point down
Rotating 180° around the Y-axis (B) points the head down. This snippet reads the current pose and returns the same X/Y/Z with the head rotated down:
arm_position, _i = get_current_posx()
return posx(arm_position[0], arm_position[1], arm_position[2], 0, 180, 0)
3. Rotate the head to a specific angle
Once the head points down, you can rotate it around its own axis by a given angle, e.g. to orient a tool. This helper takes an angle in degrees, reads the current position, and keeps the head pointed down while rotating it to that angle:
def angleToAA(angle):
arm_position, _i = get_current_posx()
# angle *= -1 # uncomment to invert rotation direction
return posx(arm_position[0], arm_position[1], arm_position[2], 0, 180, angle)
If the rotation direction is inverted for your setup, uncomment the angle *= -1 line.
4. Avoid servo lock errors on large rotations
If you jump straight to a target angle (e.g. from 10° to 350°), the robot may try to take the shortest path through a joint limit and lock a servo, which then needs to be manually unlocked and the robot restarted. To avoid this, sweep to the target angle in fixed steps instead of moving there directly, and keep track of the head’s current angle between calls.
def rotation_offset(angle):
# rotation-only offset, combined with the current pose using add_pose()
return posx(0, 0, 0, 0, 180, angle)
head_angle = 180 # tracks the head's current angle between calls
def rotate_head_angle(angle):
global head_angle
max_degrees = 360
min_degrees = 0
arm_position, _i = get_current_posx()
arm_position[3] = 0
arm_position[4] = 0
arm_position[5] = 0
# normalize the target angle into the [min_degrees, max_degrees] range
while angle > max_degrees:
angle = angle - 360
while angle < min_degrees:
angle = angle + 360
# step up towards the target angle in 90-degree increments
while head_angle < angle:
head_angle += 90
if head_angle > angle:
head_angle = angle
movel(add_pose(arm_position, rotation_offset(head_angle)), vel=30, acc=30)
# step down towards the target angle in 90-degree increments
while head_angle > angle:
head_angle -= 90
if head_angle < angle:
head_angle = angle
movel(add_pose(arm_position, rotation_offset(head_angle)), vel=30, acc=30)
return 0
The
rotate_head_angle()function remembers the head’s last commanded angle in the globalhead_anglevariable and moves towards the new target in 90° steps, instead of jumping there in one move.
5. Use it together with a move to a new position
Call rotate_head_angle() first to bring the head to the correct rotation safely, then perform the actual positional move using the rotation as an offset:
rotate_head_angle(target_angle)
movel(
add_pose(
posx(pos_x + x_offset, pos_y + y_offset, pos_z + distance, 0, 0, 0),
rotation_offset(target_angle),
),
vel=velocity,
acc=acceleration,
)
Troubleshooting
- Servo lock error after a rotation: this happens when a joint is commanded past its ±360° limit. If it happens, you need to manually unlock the servo and restart the robot — see How to set up safety area (space) limits on a Doosan robot for the general recovery procedure. Switching to the stepped
rotate_head_angle()approach above prevents this in most cases.
Check: this article renames the original angleToAA()helper from the step-4/5 example torotation_offset(), because the source used the same function name for two different signatures (one returning an absolute pose, one returning a rotation-only offset meant to be combined withadd_pose()). Only the name was changed — the logic is unmodified.
Check: the source for this section uses movel(pose, vel=30, acc=30), while other Doosan how-tos usemovel(pose, v=20, a=100)(see How to move a Doosan robot with movej, movel, and asynchronous motion commands). Verify which keyword names your DRL Studio version actually expects before relying on either.
Related
- How to move a Doosan robot with movej, movel, and asynchronous motion commands
- How to set up safety area (space) limits on a Doosan robot
Rewritten and consolidated (Sept 2026) from the original student how-to’s: How to use rotations on a Doosan robot, How to rotate Doosan Robot head without going into errors.