Why does my present position values exceed 4,095?

Summarised Qn: I would like to clarify whether it is ok to use “position read” on the motor position while in velocity mode. And why is my present position value showing higher than 4095?

Context: So I am using the XC330-T288-T motor and basically running a setup with a small plastic gear-like wheel connected to the motor directly. In my setup, the wheel is driving another thin needle-like object - almost like a rack and pinion setup. For running the motor, I am using the motor in Velocity mode at a speed of 0.7 RPM which is like a value of 3 on the range of the motor I have. Unit Value Range 0.088 [°] 0 ~ 4,095(1 rotation)

Description of Qn: I am using the velocity control mode to set it at a constant speed for about 10 seconds. And I am reading the present position to know how many degrees has the wheel rotated. So the present position values that I am getting range from 0 to 6302++, I am unsure about how many units each value of the present position represents when reading it off in Velocity Mode. Because at least in position control mode, the values range from 0 to 4095. Does it mean that the values is basically restarting when it exceeds 4095 i.e. “4095+2207 = 6302”

Code shown below

import os
# Import the time library
import time

from func_motor import *

if os.name == 'nt':
    import msvcrt
    def getch():
        return msvcrt.getch().decode()
else:
    import sys, tty, termios
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    def getch():
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch

from dynamixel_sdk import *  # Uses Dynamixel SDK library

# Control table address
ADDR_PRO_TORQUE_ENABLE = 64  # Control table address is different in Dynamixel model
ADDR_PRO_GOAL_VELOCITY = 104  # Goal Velocity
ADDR_PRO_PRESENT_VELOCITY = 128
ADDR_PRO_OPERATING_MODE = 11
ADDR_PRO_REALTIME_TICK = 120
ADDR_PRO_PRESENT_POSITION   = 132

# Protocol version
PROTOCOL_VERSION = 2.0  # See which protocol version is used in the Dynamixel

# Default setting
DXL1_ID = 2  # Dynamixel ID : 2
DXL2_ID = 3 # Dynamixel ID : 2
BAUDRATE = 57600  # Dynamixel default baudrate : 57600
DEVICENAME = 'COM3'  # Check which port is being used on your controller

TORQUE_ENABLE = 1  # Value for enabling the torque
TORQUE_DISABLE = 0  # Value for disabling the torque

DXL_MINIMUM_VELOCITY_VALUE = 0  # Dynamixel will rotate between this value
DXL_MAXIMUM_VELOCITY_VALUE = 3  # and this value
DXL_VELOCITY_MODE = 1

index = 0

dxl_goal_velocity = [DXL_MINIMUM_VELOCITY_VALUE, DXL_MAXIMUM_VELOCITY_VALUE]  # Goal

# Initialize PortHandler instance
# Set the port path
# Get methods and members of PortHandlerLinux or PortHandlerWindows
portHandler = PortHandler(DEVICENAME)

# Initialize PacketHandler instance
# Set the protocol version
# Get methods and members of Protocol1PacketHandler or Protocol2PacketHandler
packetHandler = PacketHandler(PROTOCOL_VERSION)

# Open port
if portHandler.openPort():
    print("Succeeded to open the port")
else:
    print("Failed to open the port")
    print("Press any key to terminate...")
    getch()
    quit()

# Set port baudrate
if portHandler.setBaudRate(BAUDRATE):
    print("Succeeded to change the baudrate")
else:
    print("Failed to change the baudrate")
    print("Press any key to terminate...")
    getch()
    quit()


# Disable torque for DXL1
enable_torque(portHandler, packetHandler, DXL1_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)

# Disable torque for DXL2
enable_torque(portHandler, packetHandler, DXL2_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)
    
while True:
    print("Press any key to start the motor! (or press ESC to quit!)")
    if getch() == chr(0x1b):
        break

    # Set operating mode to Velocity Control Mode
    set_operating_mode(portHandler, packetHandler, DXL1_ID, ADDR_PRO_OPERATING_MODE, DXL_VELOCITY_MODE)
    set_operating_mode(portHandler, packetHandler, DXL2_ID, ADDR_PRO_OPERATING_MODE, DXL_VELOCITY_MODE)

    # Enable torque for DXL1
    enable_torque(portHandler, packetHandler, DXL1_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)

    # Enable torque for DXL2
    enable_torque(portHandler, packetHandler, DXL2_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
    
    # Set goal velocity for DXL1
    dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_GOAL_VELOCITY,
                                                               dxl_goal_velocity[1])

    if dxl_comm_result != COMM_SUCCESS:
        print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
    elif dxl_error != 0:
        print("%s" % packetHandler.getRxPacketError(dxl_error))
    
    dxl_present_position, dxl_comm_result, dxl_error = packetHandler.read4ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_PRESENT_POSITION)
    if dxl_comm_result != COMM_SUCCESS:
        print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
    elif dxl_error != 0:
        print("%s" % packetHandler.getRxPacketError(dxl_error))

    print("PresPos:%03d" % (dxl_present_position))
    
    # Get the current time to measure elapsed time
    start_time = time.time()

    while True:
        # Get the current time
        current_time = time.time()

        # Calculate elapsed time in seconds
        elapsed_time = current_time - start_time

        # Run for 10 seconds
        if elapsed_time >= 10:
            # Stop the motors
            dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL1_ID,
                                                                       ADDR_PRO_GOAL_VELOCITY, 0)
            if dxl_comm_result != COMM_SUCCESS:
                print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
            elif dxl_error != 0:
                print("%s" % packetHandler.getRxPacketError(dxl_error))
            break
        
        dxl_present_position, dxl_comm_result, dxl_error = packetHandler.read4ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_PRESENT_POSITION)
        if dxl_comm_result != COMM_SUCCESS:
            print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
        elif dxl_error != 0:
            print("%s" % packetHandler.getRxPacketError(dxl_error))

        print("PresPos:%03d" % (dxl_present_position))
    
    # Disable torque for DXL1
    enable_torque(portHandler, packetHandler, DXL1_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)

    # Disable torque for DXL2
    enable_torque(portHandler, packetHandler, DXL2_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)

# Close the port
portHandler.closePort()```

DYNAMIXEL servos support multiturn rotation, and will track the present position up to the rollover point of ±2,147,483,647 when used in multiturn modes like velocity mode.

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.