From 8244d3291f45a2a471f00598b1f2f4c848f98db7 Mon Sep 17 00:00:00 2001 From: Alexey Nesterov Date: Fri, 30 Sep 2022 15:08:27 +1000 Subject: [PATCH] Change: all files change on files from archive SCServo_Python_200831.7z --- README.md | 10 +- scscl/read.py | 80 ------ scscl/read_write.py | 111 ------- scscl/reg_write.py | 92 ------ scscl/sync_write.py | 99 ------- scscl/wheel.py | 94 ------ scscl/write.py | 91 ------ scservo_sdk/__init__.py | 6 +- scservo_sdk/group_sync_read.py | 101 ++----- scservo_sdk/group_sync_write.py | 7 +- scservo_sdk/packet_handler.py | 10 + scservo_sdk/port_handler.py | 5 +- scservo_sdk/protocol_packet_handler.py | 286 +++++++------------ scservo_sdk/scscl.py | 104 ------- scservo_sdk/scservo_def.py | 61 +++- scservo_sdk/sms_sts.py | 111 ------- {scscl => scsservo_sdk_example}/ping.py | 22 +- scsservo_sdk_example/read_write.py | 138 +++++++++ scsservo_sdk_example/sync_read_write.py | 216 ++++++++++++++ scsservo_sdk_example/sync_write.py | 191 +++++++++++++ scsservo_sdk_source/SCServo_Python_200831.7z | Bin 0 -> 40391 bytes scsservo_sdk_source/SCServo_Python_220415.7z | Bin 8755 -> 0 bytes setup.py | 2 +- sms_sts/ping.py | 76 ----- sms_sts/read.py | 80 ------ sms_sts/read_write.py | 110 ------- sms_sts/reg_write.py | 93 ------ sms_sts/sync_read.py | 97 ------- sms_sts/sync_read_write.py | 139 --------- sms_sts/sync_write.py | 100 ------- sms_sts/wheel.py | 95 ------ sms_sts/write.py | 92 ------ 32 files changed, 780 insertions(+), 1939 deletions(-) delete mode 100644 scscl/read.py delete mode 100644 scscl/read_write.py delete mode 100644 scscl/reg_write.py delete mode 100644 scscl/sync_write.py delete mode 100644 scscl/wheel.py delete mode 100644 scscl/write.py create mode 100644 scservo_sdk/packet_handler.py delete mode 100644 scservo_sdk/scscl.py delete mode 100644 scservo_sdk/sms_sts.py rename {scscl => scsservo_sdk_example}/ping.py (79%) create mode 100644 scsservo_sdk_example/read_write.py create mode 100644 scsservo_sdk_example/sync_read_write.py create mode 100644 scsservo_sdk_example/sync_write.py create mode 100644 scsservo_sdk_source/SCServo_Python_200831.7z delete mode 100644 scsservo_sdk_source/SCServo_Python_220415.7z delete mode 100644 sms_sts/ping.py delete mode 100644 sms_sts/read.py delete mode 100644 sms_sts/read_write.py delete mode 100644 sms_sts/reg_write.py delete mode 100644 sms_sts/sync_read.py delete mode 100644 sms_sts/sync_read_write.py delete mode 100644 sms_sts/sync_write.py delete mode 100644 sms_sts/wheel.py delete mode 100644 sms_sts/write.py diff --git a/README.md b/README.md index 862cad9..855df08 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,16 @@ This is source code from [official feetech repository](https://gitee.com/ftservo/SCServoSDK). -The repository structure copies the structure of the [original library](https://gitee.com/ftservo/SCServoSDK/blob/master/SCServo_Python_220415.7z) +The repository structure copies the structure of the [original library](https://gitee.com/ftservo/SCServoSDK/blob/e4d07f43c4c34827b2e226cf5cc706576504ebeb/SCServo_Python_200831.7z) ## Structure ``` root dirrectory - |---scscl |---scservo_sdk - |---scsservo_sdk_source - |---sms_sts + |---scsservo_sdk_example ``` -The `scscl` and `sms_sts` directories contain examples of using the library. +The `scsservo_sdk_example` directories contain examples of using the library. The source code of the library is located in the `scservo_sdk` directory. @@ -34,7 +32,7 @@ Python version `Python 3.9.2`. $ cd /usr/src/ $ sudo git clone https://github.com/Adam-Software/Feetech-Servo-SDK.git $ sudo chown -R pi Feetech-Servo-SDK -$ cd Feetech-Servo-SDK/scscl +$ cd Feetech-Servo-SDK/scsservo_sdk_example $ python3 ping.py Succeeded to open the port Succeeded to change the baudrate diff --git a/scscl/read.py b/scscl/read.py deleted file mode 100644 index 18735f9..0000000 --- a/scscl/read.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(SCS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = scscl(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - # Read SCServo present position - scs_present_position, scs_present_speed, scs_comm_result, scs_error = packetHandler.ReadPosSpeed(SCS_ID) - if scs_comm_result != COMM_SUCCESS: - print(packetHandler.getTxRxResult(scs_comm_result)) - else: - print("[ID:%03d] PresPos:%d PresSpd:%d" % (SCS_ID, scs_present_position, scs_present_speed)) - if scs_error != 0: - print(packetHandler.getRxPacketError(scs_error)) - -# Close port -portHandler.closePort() diff --git a/scscl/read_write.py b/scscl/read_write.py deleted file mode 100644 index eb66fa0..0000000 --- a/scscl/read_write.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(SCS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" -SCS_MINIMUM_POSITION_VALUE = 10 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 1000 -SCS_MOVING_SPEED = 2400 # SCServo moving speed - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = scscl(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - # Write SCServo goal position/moving speed/moving acc - scs_comm_result, scs_error = packetHandler.WritePos(SCS_ID, scs_goal_position[index], 0, SCS_MOVING_SPEED) - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - elif scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - - while 1: - # Read SCServo present position - scs_present_position, scs_present_speed, scs_comm_result, scs_error = packetHandler.ReadPosSpeed(SCS_ID) - if scs_comm_result != COMM_SUCCESS: - print(packetHandler.getTxRxResult(scs_comm_result)) - elif scs_error != 0: - print(packetHandler.getRxPacketError(scs_error)) - - # Read SCServo moving status - moving, scs_comm_result, scs_error = packetHandler.ReadMoving(SCS_ID) - if scs_comm_result != COMM_SUCCESS: - print(packetHandler.getTxRxResult(scs_comm_result)) - else: - print("[ID:%03d] GoalPos:%d PresPos:%d PresSpd:%d" % (SCS_ID, scs_goal_position[index], scs_present_position, scs_present_speed)) - if scs_error != 0: - print(packetHandler.getRxPacketError(scs_error)) - - if moving==0: - break - - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort() diff --git a/scscl/reg_write.py b/scscl/reg_write.py deleted file mode 100644 index dd02f50..0000000 --- a/scscl/reg_write.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(SCS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" -SCS_MINIMUM_POSITION_VALUE = 10 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 1000 -SCS_MOVING_SPEED = 2400 # SCServo moving speed - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = scscl(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - # Write SCServo goal position/moving speed/moving acc - for scs_id in range(1, 11): - scs_comm_result, scs_error = packetHandler.RegWritePos(scs_id, scs_goal_position[index], 0, SCS_MOVING_SPEED) - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - packetHandler.RegAction() - - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort() diff --git a/scscl/sync_write.py b/scscl/sync_write.py deleted file mode 100644 index 9cf3486..0000000 --- a/scscl/sync_write.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env python -# -# ********* Sync Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(SCS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" - -SCS_MINIMUM_POSITION_VALUE = 10 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 1000 -SCS_MOVING_SPEED = 2400 # SCServo moving speed - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = scscl(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - for scs_id in range(1, 11): - # Add SCServo#1~10 goal position\moving speed\moving accc value to the Syncwrite parameter storage - scs_addparam_result = packetHandler.SyncWritePos(scs_id, scs_goal_position[index], 0, SCS_MOVING_SPEED) - if scs_addparam_result != True: - print("[ID:%03d] groupSyncWrite addparam failed" % scs_id) - - # Syncwrite goal position - scs_comm_result = packetHandler.groupSyncWrite.txPacket() - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - - # Clear syncwrite parameter storage - packetHandler.groupSyncWrite.clearParam() - - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort() diff --git a/scscl/wheel.py b/scscl/wheel.py deleted file mode 100644 index 3a0bacc..0000000 --- a/scscl/wheel.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(SCS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" -SCS_MOVING_SPEED0 = 500 # SCServo moving speed -SCS_MOVING_SPEED1 = -500 # SCServo moving speed - -index = 0 -scs_move_speed = [SCS_MOVING_SPEED0, 0, SCS_MOVING_SPEED1, 0] - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = scscl(portHandler) - -# 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() - -scs_comm_result, scs_error = packetHandler.PWMMode(SCS_ID) -if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) -elif scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - # Write SCServo goal position/moving speed/moving acc - scs_comm_result, scs_error = packetHandler.WritePWM(SCS_ID, scs_move_speed[index]) - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - - # Change move speed - index += 1 - if index == 4: - index = 0 - -# Close port -portHandler.closePort() diff --git a/scscl/write.py b/scscl/write.py deleted file mode 100644 index e6e11cb..0000000 --- a/scscl/write.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(SCS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" -SCS_MINIMUM_POSITION_VALUE = 10 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 1000 -SCS_MOVING_SPEED = 2400 # SCServo moving speed - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = scscl(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - # Write SCServo goal position/moving speed/moving acc - scs_comm_result, scs_error = packetHandler.WritePos(SCS_ID, scs_goal_position[index], 0, SCS_MOVING_SPEED) - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort() diff --git a/scservo_sdk/__init__.py b/scservo_sdk/__init__.py index bf04fa7..892f6da 100644 --- a/scservo_sdk/__init__.py +++ b/scservo_sdk/__init__.py @@ -1,8 +1,6 @@ #!/usr/bin/env python from .port_handler import * -from .protocol_packet_handler import * -from .group_sync_write import * +from .packet_handler import * from .group_sync_read import * -from .sms_sts import * -from .scscl import * +from .group_sync_write import * \ No newline at end of file diff --git a/scservo_sdk/group_sync_read.py b/scservo_sdk/group_sync_read.py index b0cf992..ba33959 100644 --- a/scservo_sdk/group_sync_read.py +++ b/scservo_sdk/group_sync_read.py @@ -3,7 +3,8 @@ from .scservo_def import * class GroupSyncRead: - def __init__(self, ph, start_address, data_length): + def __init__(self, port, ph, start_address, data_length): + self.port = port self.ph = ph self.start_address = start_address self.data_length = data_length @@ -46,33 +47,30 @@ def clearParam(self): def txPacket(self): if len(self.data_dict.keys()) == 0: - return COMM_NOT_AVAILABLE if self.is_param_changed is True or not self.param: self.makeParam() - return self.ph.syncReadTx(self.start_address, self.data_length, self.param, len(self.data_dict.keys())) + return self.ph.syncReadTx(self.port, self.start_address, self.data_length, self.param, + len(self.data_dict.keys()) * 1) def rxPacket(self): - self.last_result = True + self.last_result = False result = COMM_RX_FAIL if len(self.data_dict.keys()) == 0: return COMM_NOT_AVAILABLE - result, rxpacket = self.ph.syncReadRx(self.data_length, len(self.data_dict.keys())) - # print(rxpacket) - if len(rxpacket) >= (self.data_length+6): - for scs_id in self.data_dict: - self.data_dict[scs_id], result = self.readRx(rxpacket, scs_id, self.data_length) - if result != COMM_SUCCESS: - self.last_result = False - # print(scs_id) - else: - self.last_result = False - # print(self.last_result) + for scs_id in self.data_dict: + self.data_dict[scs_id], result, _ = self.ph.readRx(self.port, scs_id, self.data_length) + if result != COMM_SUCCESS: + return result + + if result == COMM_SUCCESS: + self.last_result = True + return result def txRxPacket(self): @@ -82,70 +80,31 @@ def txRxPacket(self): return self.rxPacket() - def readRx(self, rxpacket, scs_id, data_length): - # print(scs_id) - # print(rxpacket) - data = [] - rx_length = len(rxpacket) - # print(rx_length) - rx_index = 0; - while (rx_index+6+data_length) <= rx_length: - headpacket = [0x00, 0x00, 0x00] - while rx_index < rx_length: - headpacket[2] = headpacket[1]; - headpacket[1] = headpacket[0]; - headpacket[0] = rxpacket[rx_index]; - rx_index += 1 - if (headpacket[2] == 0xFF) and (headpacket[1] == 0xFF) and headpacket[0] == scs_id: - # print(rx_index) - break - # print(rx_index+3+data_length) - if (rx_index+3+data_length) > rx_length: - break; - if rxpacket[rx_index] != (data_length+2): - rx_index += 1 - # print(rx_index) - continue - rx_index += 1 - Error = rxpacket[rx_index] - rx_index += 1 - calSum = scs_id + (data_length+2) + Error - data = [Error] - data.extend(rxpacket[rx_index : rx_index+data_length]) - for i in range(0, data_length): - calSum += rxpacket[rx_index] - rx_index += 1 - calSum = ~calSum & 0xFF - # print(calSum) - if calSum != rxpacket[rx_index]: - return None, COMM_RX_CORRUPT - return data, COMM_SUCCESS - # print(rx_index) - return None, COMM_RX_CORRUPT - def isAvailable(self, scs_id, address, data_length): #if self.last_result is False or scs_id not in self.data_dict: if scs_id not in self.data_dict: - return False, 0 + return False if (address < self.start_address) or (self.start_address + self.data_length - data_length < address): - return False, 0 - if not self.data_dict[scs_id]: - return False, 0 - if len(self.data_dict[scs_id])<(data_length+1): - return False, 0 - return True, self.data_dict[scs_id][0] + return False + + if len(self.data_dict[scs_id])> 16) & 0xFFFF - - def scs_lobyte(self, w): - if self.scs_end==0: - return w & 0xFF - else: - return (w >> 8) & 0xFF - - def scs_hibyte(self, w): - if self.scs_end==0: - return (w >> 8) & 0xFF - else: - return w & 0xFF - def getProtocolVersion(self): return 1.0 @@ -100,33 +50,33 @@ def getTxRxResult(self, result): def getRxPacketError(self, error): if error & ERRBIT_VOLTAGE: - return "[ServoStatus] Input voltage error!" + return "[RxPacketError] Input voltage error!" if error & ERRBIT_ANGLE: - return "[ServoStatus] Angle sen error!" + return "[RxPacketError] Angle sen error!" if error & ERRBIT_OVERHEAT: - return "[ServoStatus] Overheat error!" + return "[RxPacketError] Overheat error!" if error & ERRBIT_OVERELE: - return "[ServoStatus] OverEle error!" + return "[RxPacketError] OverEle error!" if error & ERRBIT_OVERLOAD: - return "[ServoStatus] Overload error!" + return "[RxPacketError] Overload error!" return "" - def txPacket(self, txpacket): + def txPacket(self, port, txpacket): checksum = 0 total_packet_length = txpacket[PKT_LENGTH] + 4 # 4: HEADER0 HEADER1 ID LENGTH - if self.portHandler.is_using: + if port.is_using: return COMM_PORT_BUSY - self.portHandler.is_using = True + port.is_using = True # check max packet length if total_packet_length > TXPACKET_MAX_LEN: - self.portHandler.is_using = False + port.is_using = False return COMM_TX_ERROR # make packet header @@ -142,15 +92,15 @@ def txPacket(self, txpacket): #print "[TxPacket] %r" % txpacket # tx packet - self.portHandler.clearPort() - written_packet_length = self.portHandler.writePort(txpacket) + port.clearPort() + written_packet_length = port.writePort(txpacket) if total_packet_length != written_packet_length: - self.portHandler.is_using = False + port.is_using = False return COMM_TX_FAIL return COMM_SUCCESS - def rxPacket(self): + def rxPacket(self, port): rxpacket = [] result = COMM_TX_FAIL @@ -159,7 +109,7 @@ def rxPacket(self): wait_length = 6 # minimum length (HEADER0 HEADER1 ID LENGTH ERROR CHKSUM) while True: - rxpacket.extend(self.portHandler.readPort(wait_length - rx_length)) + rxpacket.extend(port.readPort(wait_length - rx_length)) rx_length = len(rxpacket) if rx_length >= wait_length: # find packet header @@ -183,7 +133,7 @@ def rxPacket(self): if rx_length < wait_length: # check timeout - if self.portHandler.isPacketTimeout(): + if port.isPacketTimeout(): if rx_length == 0: result = COMM_RX_TIMEOUT else: @@ -211,39 +161,42 @@ def rxPacket(self): else: # check timeout - if self.portHandler.isPacketTimeout(): + if port.isPacketTimeout(): if rx_length == 0: result = COMM_RX_TIMEOUT else: result = COMM_RX_CORRUPT break - self.portHandler.is_using = False + port.is_using = False + + #print "[RxPacket] %r" % rxpacket + return rxpacket, result - def txRxPacket(self, txpacket): + def txRxPacket(self, port, txpacket): rxpacket = None error = 0 # tx packet - result = self.txPacket(txpacket) + result = self.txPacket(port, txpacket) if result != COMM_SUCCESS: return rxpacket, result, error # (ID == Broadcast ID) == no need to wait for status packet or not available if (txpacket[PKT_ID] == BROADCAST_ID): - self.portHandler.is_using = False + port.is_using = False return rxpacket, result, error # set packet timeout if txpacket[PKT_INSTRUCTION] == INST_READ: - self.portHandler.setPacketTimeout(txpacket[PKT_PARAMETER0 + 1] + 6) + port.setPacketTimeout(txpacket[PKT_PARAMETER0 + 1] + 6) else: - self.portHandler.setPacketTimeout(6) # HEADER0 HEADER1 ID LENGTH ERROR CHECKSUM + port.setPacketTimeout(6) # HEADER0 HEADER1 ID LENGTH ERROR CHECKSUM # rx packet while True: - rxpacket, result = self.rxPacket() + rxpacket, result = self.rxPacket(port) if result != COMM_SUCCESS or txpacket[PKT_ID] == rxpacket[PKT_ID]: break @@ -252,7 +205,7 @@ def txRxPacket(self, txpacket): return rxpacket, result, error - def ping(self, scs_id): + def ping(self, port, scs_id): model_number = 0 error = 0 @@ -265,27 +218,27 @@ def ping(self, scs_id): txpacket[PKT_LENGTH] = 2 txpacket[PKT_INSTRUCTION] = INST_PING - rxpacket, result, error = self.txRxPacket(txpacket) + rxpacket, result, error = self.txRxPacket(port, txpacket) if result == COMM_SUCCESS: - data_read, result, error = self.readTxRx(scs_id, 3, 2) # Address 3 : Model Number + data_read, result, error = self.readTxRx(port, scs_id, 3, 2) # Address 3 : Model Number if result == COMM_SUCCESS: - model_number = self.scs_makeword(data_read[0], data_read[1]) + model_number = SCS_MAKEWORD(data_read[0], data_read[1]) return model_number, result, error - def action(self, scs_id): + def action(self, port, scs_id): txpacket = [0] * 6 txpacket[PKT_ID] = scs_id txpacket[PKT_LENGTH] = 2 txpacket[PKT_INSTRUCTION] = INST_ACTION - _, result, _ = self.txRxPacket(txpacket) + _, result, _ = self.txRxPacket(port, txpacket) return result - def readTx(self, scs_id, address, length): + def readTx(self, port, scs_id, address, length): txpacket = [0] * 8 @@ -298,15 +251,15 @@ def readTx(self, scs_id, address, length): txpacket[PKT_PARAMETER0 + 0] = address txpacket[PKT_PARAMETER0 + 1] = length - result = self.txPacket(txpacket) + result = self.txPacket(port, txpacket) # set packet timeout if result == COMM_SUCCESS: - self.portHandler.setPacketTimeout(length + 6) + port.setPacketTimeout(length + 6) return result - def readRx(self, scs_id, length): + def readRx(self, port, scs_id, length): result = COMM_TX_FAIL error = 0 @@ -314,7 +267,7 @@ def readRx(self, scs_id, length): data = [] while True: - rxpacket, result = self.rxPacket() + rxpacket, result = self.rxPacket(port) if result != COMM_SUCCESS or rxpacket[PKT_ID] == scs_id: break @@ -322,11 +275,11 @@ def readRx(self, scs_id, length): if result == COMM_SUCCESS and rxpacket[PKT_ID] == scs_id: error = rxpacket[PKT_ERROR] - data.extend(rxpacket[PKT_PARAMETER0 : PKT_PARAMETER0+length]) + data.extend(rxpacket[PKT_PARAMETER0: PKT_PARAMETER0 + length]) return data, result, error - def readTxRx(self, scs_id, address, length): + def readTxRx(self, port, scs_id, address, length): txpacket = [0] * 8 data = [] @@ -339,56 +292,56 @@ def readTxRx(self, scs_id, address, length): txpacket[PKT_PARAMETER0 + 0] = address txpacket[PKT_PARAMETER0 + 1] = length - rxpacket, result, error = self.txRxPacket(txpacket) + rxpacket, result, error = self.txRxPacket(port, txpacket) if result == COMM_SUCCESS: error = rxpacket[PKT_ERROR] - data.extend(rxpacket[PKT_PARAMETER0 : PKT_PARAMETER0+length]) + data.extend(rxpacket[PKT_PARAMETER0: PKT_PARAMETER0 + length]) return data, result, error - def read1ByteTx(self, scs_id, address): - return self.readTx(scs_id, address, 1) + def read1ByteTx(self, port, scs_id, address): + return self.readTx(port, scs_id, address, 1) - def read1ByteRx(self, scs_id): - data, result, error = self.readRx(scs_id, 1) + def read1ByteRx(self, port, scs_id): + data, result, error = self.readRx(port, scs_id, 1) data_read = data[0] if (result == COMM_SUCCESS) else 0 return data_read, result, error - def read1ByteTxRx(self, scs_id, address): - data, result, error = self.readTxRx(scs_id, address, 1) + def read1ByteTxRx(self, port, scs_id, address): + data, result, error = self.readTxRx(port, scs_id, address, 1) data_read = data[0] if (result == COMM_SUCCESS) else 0 return data_read, result, error - def read2ByteTx(self, scs_id, address): - return self.readTx(scs_id, address, 2) + def read2ByteTx(self, port, scs_id, address): + return self.readTx(port, scs_id, address, 2) - def read2ByteRx(self, scs_id): - data, result, error = self.readRx(scs_id, 2) - data_read = self.scs_makeword(data[0], data[1]) if (result == COMM_SUCCESS) else 0 + def read2ByteRx(self, port, scs_id): + data, result, error = self.readRx(port, scs_id, 2) + data_read = SCS_MAKEWORD(data[0], data[1]) if (result == COMM_SUCCESS) else 0 return data_read, result, error - def read2ByteTxRx(self, scs_id, address): - data, result, error = self.readTxRx(scs_id, address, 2) - data_read = self.scs_makeword(data[0], data[1]) if (result == COMM_SUCCESS) else 0 + def read2ByteTxRx(self, port, scs_id, address): + data, result, error = self.readTxRx(port, scs_id, address, 2) + data_read = SCS_MAKEWORD(data[0], data[1]) if (result == COMM_SUCCESS) else 0 return data_read, result, error - def read4ByteTx(self, scs_id, address): - return self.readTx(scs_id, address, 4) + def read4ByteTx(self, port, scs_id, address): + return self.readTx(port, scs_id, address, 4) - def read4ByteRx(self, scs_id): - data, result, error = self.readRx(scs_id, 4) - data_read = self.scs_makedword(self.scs_makeword(data[0], data[1]), - self.scs_makeword(data[2], data[3])) if (result == COMM_SUCCESS) else 0 + def read4ByteRx(self, port, scs_id): + data, result, error = self.readRx(port, scs_id, 4) + data_read = SCS_MAKEDWORD(SCS_MAKEWORD(data[0], data[1]), + SCS_MAKEWORD(data[2], data[3])) if (result == COMM_SUCCESS) else 0 return data_read, result, error - def read4ByteTxRx(self, scs_id, address): - data, result, error = self.readTxRx(scs_id, address, 4) - data_read = self.scs_makedword(self.scs_makeword(data[0], data[1]), - self.scs_makeword(data[2], data[3])) if (result == COMM_SUCCESS) else 0 + def read4ByteTxRx(self, port, scs_id, address): + data, result, error = self.readTxRx(port, scs_id, address, 4) + data_read = SCS_MAKEDWORD(SCS_MAKEWORD(data[0], data[1]), + SCS_MAKEWORD(data[2], data[3])) if (result == COMM_SUCCESS) else 0 return data_read, result, error - def writeTxOnly(self, scs_id, address, length, data): + def writeTxOnly(self, port, scs_id, address, length, data): txpacket = [0] * (length + 7) txpacket[PKT_ID] = scs_id @@ -398,12 +351,12 @@ def writeTxOnly(self, scs_id, address, length, data): txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length] - result = self.txPacket(txpacket) - self.portHandler.is_using = False + result = self.txPacket(port, txpacket) + port.is_using = False return result - def writeTxRx(self, scs_id, address, length, data): + def writeTxRx(self, port, scs_id, address, length, data): txpacket = [0] * (length + 7) txpacket[PKT_ID] = scs_id @@ -412,41 +365,41 @@ def writeTxRx(self, scs_id, address, length, data): txpacket[PKT_PARAMETER0] = address txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length] - rxpacket, result, error = self.txRxPacket(txpacket) + rxpacket, result, error = self.txRxPacket(port, txpacket) return result, error - def write1ByteTxOnly(self, scs_id, address, data): + def write1ByteTxOnly(self, port, scs_id, address, data): data_write = [data] - return self.writeTxOnly(scs_id, address, 1, data_write) + return self.writeTxOnly(port, scs_id, address, 1, data_write) - def write1ByteTxRx(self, scs_id, address, data): + def write1ByteTxRx(self, port, scs_id, address, data): data_write = [data] - return self.writeTxRx(scs_id, address, 1, data_write) - - def write2ByteTxOnly(self, scs_id, address, data): - data_write = [self.scs_lobyte(data), self.scs_hibyte(data)] - return self.writeTxOnly(scs_id, address, 2, data_write) - - def write2ByteTxRx(self, scs_id, address, data): - data_write = [self.scs_lobyte(data), self.scs_hibyte(data)] - return self.writeTxRx(scs_id, address, 2, data_write) - - def write4ByteTxOnly(self, scs_id, address, data): - data_write = [self.scs_lobyte(self.scs_loword(data)), - self.scs_hibyte(self.scs_loword(data)), - self.scs_lobyte(self.scs_hiword(data)), - self.scs_hibyte(self.scs_hiword(data))] - return self.writeTxOnly(scs_id, address, 4, data_write) - - def write4ByteTxRx(self, scs_id, address, data): - data_write = [self.scs_lobyte(self.scs_loword(data)), - self.scs_hibyte(self.scs_loword(data)), - self.scs_lobyte(self.scs_hiword(data)), - self.scs_hibyte(self.scs_hiword(data))] - return self.writeTxRx(scs_id, address, 4, data_write) - - def regWriteTxOnly(self, scs_id, address, length, data): + return self.writeTxRx(port, scs_id, address, 1, data_write) + + def write2ByteTxOnly(self, port, scs_id, address, data): + data_write = [SCS_LOBYTE(data), SCS_HIBYTE(data)] + return self.writeTxOnly(port, scs_id, address, 2, data_write) + + def write2ByteTxRx(self, port, scs_id, address, data): + data_write = [SCS_LOBYTE(data), SCS_HIBYTE(data)] + return self.writeTxRx(port, scs_id, address, 2, data_write) + + def write4ByteTxOnly(self, port, scs_id, address, data): + data_write = [SCS_LOBYTE(SCS_LOWORD(data)), + SCS_HIBYTE(SCS_LOWORD(data)), + SCS_LOBYTE(SCS_HIWORD(data)), + SCS_HIBYTE(SCS_HIWORD(data))] + return self.writeTxOnly(port, scs_id, address, 4, data_write) + + def write4ByteTxRx(self, port, scs_id, address, data): + data_write = [SCS_LOBYTE(SCS_LOWORD(data)), + SCS_HIBYTE(SCS_LOWORD(data)), + SCS_LOBYTE(SCS_HIWORD(data)), + SCS_HIBYTE(SCS_HIWORD(data))] + return self.writeTxRx(port, scs_id, address, 4, data_write) + + def regWriteTxOnly(self, port, scs_id, address, length, data): txpacket = [0] * (length + 7) txpacket[PKT_ID] = scs_id @@ -456,12 +409,12 @@ def regWriteTxOnly(self, scs_id, address, length, data): txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length] - result = self.txPacket(txpacket) - self.portHandler.is_using = False + result = self.txPacket(port, txpacket) + port.is_using = False return result - def regWriteTxRx(self, scs_id, address, length, data): + def regWriteTxRx(self, port, scs_id, address, length, data): txpacket = [0] * (length + 7) txpacket[PKT_ID] = scs_id @@ -471,11 +424,11 @@ def regWriteTxRx(self, scs_id, address, length, data): txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length] - _, result, error = self.txRxPacket(txpacket) + _, result, error = self.txRxPacket(port, txpacket) return result, error - def syncReadTx(self, start_address, data_length, param, param_length): + def syncReadTx(self, port, start_address, data_length, param, param_length): txpacket = [0] * (param_length + 8) # 8: HEADER0 HEADER1 ID LEN INST START_ADDR DATA_LEN CHKSUM @@ -487,33 +440,14 @@ def syncReadTx(self, start_address, data_length, param, param_length): txpacket[PKT_PARAMETER0 + 2: PKT_PARAMETER0 + 2 + param_length] = param[0: param_length] - # print(txpacket) - result = self.txPacket(txpacket) + result = self.txPacket(port, txpacket) + if result == COMM_SUCCESS: + port.setPacketTimeout((6 + data_length) * param_length) + return result - def syncReadRx(self, data_length, param_length): - wait_length = (6 + data_length) * param_length - self.portHandler.setPacketTimeout(wait_length) - rxpacket = [] - rx_length = 0 - while True: - rxpacket.extend(self.portHandler.readPort(wait_length - rx_length)) - rx_length = len(rxpacket) - if rx_length >= wait_length: - result = COMM_SUCCESS - break - else: - # check timeout - if self.portHandler.isPacketTimeout(): - if rx_length == 0: - result = COMM_RX_TIMEOUT - else: - result = COMM_RX_CORRUPT - break - self.portHandler.is_using = False - return result, rxpacket - def syncWriteTxOnly(self, start_address, data_length, param, param_length): + def syncWriteTxOnly(self, port, start_address, data_length, param, param_length): txpacket = [0] * (param_length + 8) # 8: HEADER0 HEADER1 ID LEN INST START_ADDR DATA_LEN ... CHKSUM @@ -525,6 +459,6 @@ def syncWriteTxOnly(self, start_address, data_length, param, param_length): txpacket[PKT_PARAMETER0 + 2: PKT_PARAMETER0 + 2 + param_length] = param[0: param_length] - _, result, _ = self.txRxPacket(txpacket) + _, result, _ = self.txRxPacket(port, txpacket) - return result + return result \ No newline at end of file diff --git a/scservo_sdk/scscl.py b/scservo_sdk/scscl.py deleted file mode 100644 index 4044bc2..0000000 --- a/scservo_sdk/scscl.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python - -from .scservo_def import * -from .protocol_packet_handler import * -from .group_sync_write import * - -#波特率定义 -SCSCL_1M = 0 -SCSCL_0_5M = 1 -SCSCL_250K = 2 -SCSCL_128K = 3 -SCSCL_115200 = 4 -SCSCL_76800 = 5 -SCSCL_57600 = 6 -SCSCL_38400 = 7 - -#内存表定义 -#-------EPROM(只读)-------- -SCSCL_MODEL_L = 3 -SCSCL_MODEL_H = 4 - -#-------EPROM(读写)-------- -scs_id = 5 -SCSCL_BAUD_RATE = 6 -SCSCL_MIN_ANGLE_LIMIT_L = 9 -SCSCL_MIN_ANGLE_LIMIT_H = 10 -SCSCL_MAX_ANGLE_LIMIT_L = 11 -SCSCL_MAX_ANGLE_LIMIT_H = 12 -SCSCL_CW_DEAD = 26 -SCSCL_CCW_DEAD = 27 - -#-------SRAM(读写)-------- -SCSCL_TORQUE_ENABLE = 40 -SCSCL_GOAL_POSITION_L = 42 -SCSCL_GOAL_POSITION_H = 43 -SCSCL_GOAL_TIME_L = 44 -SCSCL_GOAL_TIME_H = 45 -SCSCL_GOAL_SPEED_L = 46 -SCSCL_GOAL_SPEED_H = 47 -SCSCL_LOCK = 48 - -#-------SRAM(只读)-------- -SCSCL_PRESENT_POSITION_L = 56 -SCSCL_PRESENT_POSITION_H = 57 -SCSCL_PRESENT_SPEED_L = 58 -SCSCL_PRESENT_SPEED_H = 59 -SCSCL_PRESENT_LOAD_L = 60 -SCSCL_PRESENT_LOAD_H = 61 -SCSCL_PRESENT_VOLTAGE = 62 -SCSCL_PRESENT_TEMPERATURE = 63 -SCSCL_MOVING = 66 -SCSCL_PRESENT_CURRENT_L = 69 -SCSCL_PRESENT_CURRENT_H = 70 - -class scscl(protocol_packet_handler): - def __init__(self, portHandler): - protocol_packet_handler.__init__(self, portHandler, 1) - self.groupSyncWrite = GroupSyncWrite(self, SCSCL_GOAL_POSITION_L, 6) - - def WritePos(self, scs_id, position, time, speed): - txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)] - return self.writeTxRx(scs_id, SCSCL_GOAL_POSITION_L, len(txpacket), txpacket) - - def ReadPos(self, scs_id): - scs_present_position, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SCSCL_PRESENT_POSITION_L) - return scs_present_position, scs_comm_result, scs_error - - def ReadSpeed(self, scs_id): - scs_present_speed, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SCSCL_PRESENT_SPEED_L) - return self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error - - def ReadPosSpeed(self, scs_id): - scs_present_position_speed, scs_comm_result, scs_error = self.read4ByteTxRx(scs_id, SCSCL_PRESENT_POSITION_L) - scs_present_position = self.scs_loword(scs_present_position_speed) - scs_present_speed = self.scs_hiword(scs_present_position_speed) - return scs_present_position, self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error - - def ReadMoving(self, scs_id): - moving, scs_comm_result, scs_error = self.read1ByteTxRx(scs_id, SCSCL_MOVING) - return moving, scs_comm_result, scs_error - - def SyncWritePos(self, scs_id, position, time, speed): - txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)] - return self.groupSyncWrite.addParam(scs_id, txpacket) - - def RegWritePos(self, scs_id, position, time, speed): - txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)] - return self.regWriteTxRx(scs_id, SCSCL_GOAL_POSITION_L, len(txpacket), txpacket) - - def RegAction(self): - return self.action(BROADCAST_ID) - - def PWMMode(self, scs_id): - txpacket = [0, 0, 0, 0] - return self.writeTxRx(scs_id, SCSCL_MIN_ANGLE_LIMIT_L, len(txpacket), txpacket) - - def WritePWM(self, scs_id, time): - return self.write2ByteTxRx(scs_id, SCSCL_GOAL_TIME_L, self.scs_toscs(time, 10)) - - def LockEprom(self, scs_id): - return self.write1ByteTxRx(scs_id, SCSCL_LOCK, 1) - - def unLockEprom(self, scs_id): - return self.write1ByteTxRx(scs_id, SCSCL_LOCK, 0) diff --git a/scservo_sdk/scservo_def.py b/scservo_sdk/scservo_def.py index d331d9b..8a1de98 100644 --- a/scservo_sdk/scservo_def.py +++ b/scservo_sdk/scservo_def.py @@ -4,7 +4,7 @@ MAX_ID = 0xFC # 252 SCS_END = 0 -# Instruction for SCS Protocol +# Instruction for DXL Protocol INST_PING = 1 INST_READ = 2 INST_WRITE = 3 @@ -23,3 +23,62 @@ COMM_RX_TIMEOUT = -6 # There is no status packet COMM_RX_CORRUPT = -7 # Incorrect status packet COMM_NOT_AVAILABLE = -9 # + + +# Macro for Control Table Value +def SCS_GETEND(): + global SCS_END + return SCS_END + +def SCS_SETEND(e): + global SCS_END + SCS_END = e + +def SCS_TOHOST(a, b): + if (a & (1<> 16) & 0xFFFF + + +def SCS_LOBYTE(w): + global SCS_END + if SCS_END==0: + return w & 0xFF + else: + return (w >> 8) & 0xFF + + +def SCS_HIBYTE(w): + global SCS_END + if SCS_END==0: + return (w >> 8) & 0xFF + else: + return w & 0xFF \ No newline at end of file diff --git a/scservo_sdk/sms_sts.py b/scservo_sdk/sms_sts.py deleted file mode 100644 index cb91a9a..0000000 --- a/scservo_sdk/sms_sts.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python - -from .scservo_def import * -from .protocol_packet_handler import * -from .group_sync_read import * -from .group_sync_write import * - -#波特率定义 -SMS_STS_1M = 0 -SMS_STS_0_5M = 1 -SMS_STS_250K = 2 -SMS_STS_128K = 3 -SMS_STS_115200 = 4 -SMS_STS_76800 = 5 -SMS_STS_57600 = 6 -SMS_STS_38400 = 7 - -#内存表定义 -#-------EPROM(只读)-------- -SMS_STS_MODEL_L = 3 -SMS_STS_MODEL_H = 4 - -#-------EPROM(读写)-------- -SMS_STS_ID = 5 -SMS_STS_BAUD_RATE = 6 -SMS_STS_MIN_ANGLE_LIMIT_L = 9 -SMS_STS_MIN_ANGLE_LIMIT_H = 10 -SMS_STS_MAX_ANGLE_LIMIT_L = 11 -SMS_STS_MAX_ANGLE_LIMIT_H = 12 -SMS_STS_CW_DEAD = 26 -SMS_STS_CCW_DEAD = 27 -SMS_STS_OFS_L = 31 -SMS_STS_OFS_H = 32 -SMS_STS_MODE = 33 - -#-------SRAM(读写)-------- -SMS_STS_TORQUE_ENABLE = 40 -SMS_STS_ACC = 41 -SMS_STS_GOAL_POSITION_L = 42 -SMS_STS_GOAL_POSITION_H = 43 -SMS_STS_GOAL_TIME_L = 44 -SMS_STS_GOAL_TIME_H = 45 -SMS_STS_GOAL_SPEED_L = 46 -SMS_STS_GOAL_SPEED_H = 47 -SMS_STS_LOCK = 55 - -#-------SRAM(只读)-------- -SMS_STS_PRESENT_POSITION_L = 56 -SMS_STS_PRESENT_POSITION_H = 57 -SMS_STS_PRESENT_SPEED_L = 58 -SMS_STS_PRESENT_SPEED_H = 59 -SMS_STS_PRESENT_LOAD_L = 60 -SMS_STS_PRESENT_LOAD_H = 61 -SMS_STS_PRESENT_VOLTAGE = 62 -SMS_STS_PRESENT_TEMPERATURE = 63 -SMS_STS_MOVING = 66 -SMS_STS_PRESENT_CURRENT_L = 69 -SMS_STS_PRESENT_CURRENT_H = 70 - -class sms_sts(protocol_packet_handler): - def __init__(self, portHandler): - protocol_packet_handler.__init__(self, portHandler, 0) - self.groupSyncWrite = GroupSyncWrite(self, SMS_STS_ACC, 7) - - def WritePosEx(self, scs_id, position, speed, acc): - txpacket = [acc, self.scs_lobyte(position), self.scs_hibyte(position), 0, 0, self.scs_lobyte(speed), self.scs_hibyte(speed)] - return self.writeTxRx(scs_id, SMS_STS_ACC, len(txpacket), txpacket) - - def ReadPos(self, scs_id): - scs_present_position, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SMS_STS_PRESENT_POSITION_L) - return self.scs_tohost(scs_present_position, 15), scs_comm_result, scs_error - - def ReadSpeed(self, scs_id): - scs_present_speed, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SMS_STS_PRESENT_SPEED_L) - return self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error - - def ReadPosSpeed(self, scs_id): - scs_present_position_speed, scs_comm_result, scs_error = self.read4ByteTxRx(scs_id, SMS_STS_PRESENT_POSITION_L) - scs_present_position = self.scs_loword(scs_present_position_speed) - scs_present_speed = self.scs_hiword(scs_present_position_speed) - return self.scs_tohost(scs_present_position, 15), self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error - - def ReadMoving(self, scs_id): - moving, scs_comm_result, scs_error = self.read1ByteTxRx(scs_id, SMS_STS_MOVING) - return moving, scs_comm_result, scs_error - - def SyncWritePosEx(self, scs_id, position, speed, acc): - txpacket = [acc, self.scs_lobyte(position), self.scs_hibyte(position), 0, 0, self.scs_lobyte(speed), self.scs_hibyte(speed)] - return self.groupSyncWrite.addParam(scs_id, txpacket) - - def RegWritePosEx(self, scs_id, position, speed, acc): - txpacket = [acc, self.scs_lobyte(position), self.scs_hibyte(position), 0, 0, self.scs_lobyte(speed), self.scs_hibyte(speed)] - return self.regWriteTxRx(scs_id, SMS_STS_ACC, len(txpacket), txpacket) - - def RegAction(self): - return self.action(BROADCAST_ID) - - def WheelMode(self, scs_id): - return self.write1ByteTxRx(scs_id, SMS_STS_MODE, 1) - - def WriteSpec(self, scs_id, speed, acc): - speed = self.scs_toscs(speed, 15) - txpacket = [acc, 0, 0, 0, 0, self.scs_lobyte(speed), self.scs_hibyte(speed)] - return self.writeTxRx(scs_id, SMS_STS_ACC, len(txpacket), txpacket) - - def LockEprom(self, scs_id): - return self.write1ByteTxRx(scs_id, SMS_STS_LOCK, 1) - - def unLockEprom(self, scs_id): - return self.write1ByteTxRx(scs_id, SMS_STS_LOCK, 0) - diff --git a/scscl/ping.py b/scsservo_sdk_example/ping.py similarity index 79% rename from scscl/ping.py rename to scsservo_sdk_example/ping.py index a9e0df1..cdc8947 100644 --- a/scscl/ping.py +++ b/scsservo_sdk_example/ping.py @@ -4,10 +4,10 @@ # # # Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(SCS), and an URT +# This example is tested with a SCServo(STS/SMS/SCS), and an URT +# Be sure that SCServo(STS/SMS/SCS) properties are already set as %% ID : 1 / Baudnum : 6 (Baudrate : 1000000) # -import sys import os if os.name == 'nt': @@ -26,15 +26,16 @@ def getch(): termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library +from scservo_sdk import * # Uses SCServo SDK library # Default setting -SCS_ID = 1 # SCServo ID : 1 +SCS_ID = 13 # SCServo ID : 1 BAUDRATE = 1000000 # SCServo default baudrate : 1000000 DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" +protocol_end = 0 # SCServo bit end(STS/SMS=0, SCS=1) + # Initialize PortHandler instance # Set the port path # Get methods and members of PortHandlerLinux or PortHandlerWindows @@ -42,7 +43,7 @@ def getch(): # Initialize PacketHandler instance # Get methods and members of Protocol -packetHandler = scscl(portHandler) +packetHandler = PacketHandler(protocol_end) # Open port if portHandler.openPort(): @@ -65,14 +66,13 @@ def getch(): # Try to ping the SCServo # Get SCServo model number -scs_model_number, scs_comm_result, scs_error = packetHandler.ping(SCS_ID) +scs_model_number, scs_comm_result, scs_error = packetHandler.ping(portHandler, SCS_ID) if scs_comm_result != COMM_SUCCESS: print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) else: print("[ID:%03d] ping Succeeded. SCServo model number : %d" % (SCS_ID, scs_model_number)) -if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) # Close port -portHandler.closePort() - +portHandler.closePort() \ No newline at end of file diff --git a/scsservo_sdk_example/read_write.py b/scsservo_sdk_example/read_write.py new file mode 100644 index 0000000..f7992d7 --- /dev/null +++ b/scsservo_sdk_example/read_write.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# +# ********* Gen Write Example ********* +# +# +# Available SCServo model on this example : All models using Protocol SCS +# This example is tested with a SCServo(STS/SMS/SCS), and an URT +# Be sure that SCServo(STS/SMS/SCS) properties are already set as %% ID : 1 / Baudnum : 6 (Baudrate : 1000000) +# + +import os + +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 scservo_sdk import * # Uses SCServo SDK library + +# Control table address +ADDR_SCS_TORQUE_ENABLE = 40 +ADDR_SCS_GOAL_ACC = 41 +ADDR_SCS_GOAL_POSITION = 42 +ADDR_SCS_GOAL_SPEED = 46 +ADDR_SCS_PRESENT_POSITION = 56 + +# Default setting +SCS_ID = 1 # SCServo ID : 1 +BAUDRATE = 1000000 # SCServo default baudrate : 1000000 +DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller + # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" + +SCS_MINIMUM_POSITION_VALUE = 100 # SCServo will rotate between this value +SCS_MAXIMUM_POSITION_VALUE = 4000 # and this value (note that the SCServo would not move when the position value is out of movable range. Check e-manual about the range of the SCServo you use.) +SCS_MOVING_STATUS_THRESHOLD = 20 # SCServo moving status threshold +SCS_MOVING_SPEED = 0 # SCServo moving speed +SCS_MOVING_ACC = 0 # SCServo moving acc +protocol_end = 0 # SCServo bit end(STS/SMS=0, SCS=1) + +index = 0 +scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position + + +# Initialize PortHandler instance +# Set the port path +# Get methods and members of PortHandlerLinux or PortHandlerWindows +portHandler = PortHandler(DEVICENAME) + +# Initialize PacketHandler instance +# Get methods and members of Protocol +packetHandler = PacketHandler(protocol_end) + +# 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() + +# Write SCServo acc +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS_ID, ADDR_SCS_GOAL_ACC, SCS_MOVING_ACC) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# Write SCServo speed +scs_comm_result, scs_error = packetHandler.write2ByteTxRx(portHandler, SCS_ID, ADDR_SCS_GOAL_SPEED, SCS_MOVING_SPEED) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +while 1: + print("Press any key to continue! (or press ESC to quit!)") + if getch() == chr(0x1b): + break + + # Write SCServo goal position + scs_comm_result, scs_error = packetHandler.write2ByteTxRx(portHandler, SCS_ID, ADDR_SCS_GOAL_POSITION, scs_goal_position[index]) + if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) + elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + + while 1: + # Read SCServo present position + scs_present_position_speed, scs_comm_result, scs_error = packetHandler.read4ByteTxRx(portHandler, SCS_ID, ADDR_SCS_PRESENT_POSITION) + if scs_comm_result != COMM_SUCCESS: + print(packetHandler.getTxRxResult(scs_comm_result)) + elif scs_error != 0: + print(packetHandler.getRxPacketError(scs_error)) + + scs_present_position = SCS_LOWORD(scs_present_position_speed) + scs_present_speed = SCS_HIWORD(scs_present_position_speed) + print("[ID:%03d] GoalPos:%03d PresPos:%03d PresSpd:%03d" + % (SCS_ID, scs_goal_position[index], scs_present_position, SCS_TOHOST(scs_present_speed, 15))) + + if not (abs(scs_goal_position[index] - scs_present_position_speed) > SCS_MOVING_STATUS_THRESHOLD): + break + + + # Change goal position + if index == 0: + index = 1 + else: + index = 0 + +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS_ID, ADDR_SCS_TORQUE_ENABLE, 0) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) +# Close port +portHandler.closePort() \ No newline at end of file diff --git a/scsservo_sdk_example/sync_read_write.py b/scsservo_sdk_example/sync_read_write.py new file mode 100644 index 0000000..dd674d0 --- /dev/null +++ b/scsservo_sdk_example/sync_read_write.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python +# +# ********* Sync Read and Sync Write Example ********* +# +# +# Available SCServo model on this example : All models using Protocol SCS +# This example is tested with a SCServo(STS/SMS), and an URT +# Be sure that SCServo(STS/SMS) properties are already set as %% ID : 1 / Baudnum : 6 (Baudrate : 1000000) +# + +import os + +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 scservo_sdk import * # Uses SCServo SDK library + +# Control table address +ADDR_SCS_TORQUE_ENABLE = 40 +ADDR_STS_GOAL_ACC = 41 +ADDR_STS_GOAL_POSITION = 42 +ADDR_STS_GOAL_SPEED = 46 +ADDR_STS_PRESENT_POSITION = 56 + +# Default setting +SCS1_ID = 1 # SCServo#1 ID : 1 +SCS2_ID = 2 # SCServo#1 ID : 2 +BAUDRATE = 1000000 # SCServo default baudrate : 1000000 +DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller + # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" + +SCS_MINIMUM_POSITION_VALUE = 100 # SCServo will rotate between this value +SCS_MAXIMUM_POSITION_VALUE = 4000 # and this value (note that the SCServo would not move when the position value is out of movable range. Check e-manual about the range of the SCServo you use.) +SCS_MOVING_STATUS_THRESHOLD = 20 # SCServo moving status threshold +SCS_MOVING_SPEED = 0 # SCServo moving speed +SCS_MOVING_ACC = 0 # SCServo moving acc +protocol_end = 0 # SCServo bit end(STS/SMS=0, SCS=1) + +index = 0 +scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position + +# Initialize PortHandler instance +# Set the port path +# Get methods and members of PortHandlerLinux or PortHandlerWindows +portHandler = PortHandler(DEVICENAME) + +# Initialize PacketHandler instance +# Get methods and members of Protocol +packetHandler = PacketHandler(protocol_end) + +# Initialize GroupSyncWrite instance +groupSyncWrite = GroupSyncWrite(portHandler, packetHandler, ADDR_STS_GOAL_POSITION, 2) + +# Initialize GroupSyncRead instace for Present Position +groupSyncRead = GroupSyncRead(portHandler, packetHandler, ADDR_STS_PRESENT_POSITION, 4) + +# 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() + +# SCServo#1 acc +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS1_ID, ADDR_STS_GOAL_ACC, SCS_MOVING_ACC) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# SCServo#2 acc +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS2_ID, ADDR_STS_GOAL_ACC, SCS_MOVING_ACC) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# SCServo#1 speed +scs_comm_result, scs_error = packetHandler.write2ByteTxRx(portHandler, SCS1_ID, ADDR_STS_GOAL_SPEED, SCS_MOVING_SPEED) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# SCServo#2 speed +scs_comm_result, scs_error = packetHandler.write2ByteTxRx(portHandler, SCS2_ID, ADDR_STS_GOAL_SPEED, SCS_MOVING_SPEED) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# Add parameter storage for SCServo#1 present position value +scs_addparam_result = groupSyncRead.addParam(SCS1_ID) +if scs_addparam_result != True: + print("[ID:%03d] groupSyncRead addparam failed" % SCS1_ID) + quit() + +# Add parameter storage for SCServo#2 present position value +scs_addparam_result = groupSyncRead.addParam(SCS2_ID) +if scs_addparam_result != True: + print("[ID:%03d] groupSyncRead addparam failed" % SCS2_ID) + quit() + +while 1: + print("Press any key to continue! (or press ESC to quit!)") + if getch() == chr(0x1b): + break + + # Allocate goal position value into byte array + param_goal_position = [SCS_LOBYTE(scs_goal_position[index]), SCS_HIBYTE(scs_goal_position[index])] + + # Add SCServo#1 goal position value to the Syncwrite parameter storage + scs_addparam_result = groupSyncWrite.addParam(SCS1_ID, param_goal_position) + if scs_addparam_result != True: + print("[ID:%03d] groupSyncWrite addparam failed" % SCS1_ID) + quit() + + # Add SCServo#2 goal position value to the Syncwrite parameter storage + scs_addparam_result = groupSyncWrite.addParam(SCS2_ID, param_goal_position) + if scs_addparam_result != True: + print("[ID:%03d] groupSyncWrite addparam failed" % SCS2_ID) + quit() + + # Syncwrite goal position + scs_comm_result = groupSyncWrite.txPacket() + if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) + + # Clear syncwrite parameter storage + groupSyncWrite.clearParam() + + while 1: + # Syncread present position + scs_comm_result = groupSyncRead.txRxPacket() + if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) + + # Check if groupsyncread data of SCServo#1 is available + scs_getdata_result = groupSyncRead.isAvailable(SCS1_ID, ADDR_STS_PRESENT_POSITION, 4) + scs1_present_position_speed = 0 + scs2_present_position_speed = 0 + if scs_getdata_result == True: + # Get SCServo#1 present position value + scs1_present_position_speed = groupSyncRead.getData(SCS1_ID, ADDR_STS_PRESENT_POSITION, 4) + else: + print("[ID:%03d] groupSyncRead getdata failed" % SCS1_ID) + + # Check if groupsyncread data of SCServo#2 is available + scs_getdata_result = groupSyncRead.isAvailable(SCS2_ID, ADDR_STS_PRESENT_POSITION, 4) + if scs_getdata_result == True: + # Get SCServo#2 present position value + scs2_present_position_speed = groupSyncRead.getData(SCS2_ID, ADDR_STS_PRESENT_POSITION, 4) + else: + print("[ID:%03d] groupSyncRead getdata failed" % SCS2_ID) + + scs1_present_position = SCS_LOWORD(scs1_present_position_speed) + scs1_present_speed = SCS_HIWORD(scs1_present_position_speed) + scs2_present_position = SCS_LOWORD(scs2_present_position_speed) + scs2_present_speed = SCS_HIWORD(scs2_present_position_speed) + print("[ID:%03d] GoalPos:%03d PresPos:%03d PresSpd:%03d\t[ID:%03d] GoalPos:%03d PresPos:%03d PresSpd:%03d" + % (SCS1_ID, scs_goal_position[index], scs1_present_position, SCS_TOHOST(scs1_present_speed, 15), + SCS2_ID, scs_goal_position[index], scs2_present_position, SCS_TOHOST(scs2_present_speed, 15))) + + if not ((abs(scs_goal_position[index] - scs1_present_position_speed) > SCS_MOVING_STATUS_THRESHOLD) and (abs(scs_goal_position[index] - scs2_present_position_speed) > SCS_MOVING_STATUS_THRESHOLD)): + break + + # Change goal position + if index == 0: + index = 1 + else: + index = 0 + +# Clear syncread parameter storage +groupSyncRead.clearParam() + +# SCServo#1 torque +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS1_ID, ADDR_SCS_TORQUE_ENABLE, 0) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# SCServo#2 torque +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS2_ID, ADDR_SCS_TORQUE_ENABLE, 0) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# Close port +portHandler.closePort() \ No newline at end of file diff --git a/scsservo_sdk_example/sync_write.py b/scsservo_sdk_example/sync_write.py new file mode 100644 index 0000000..4253970 --- /dev/null +++ b/scsservo_sdk_example/sync_write.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# +# ********* Sync Write Example ********* +# +# +# Available SCServo model on this example : All models using Protocol SCS +# This example is tested with a SCServo(STS/SMS/SCS), and an URT +# Be sure that SCServo(STS/SMS/SCS) properties are already set as %% ID : 1 / Baudnum : 6 (Baudrate : 1000000) +# + +import os + +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 scservo_sdk import * # Uses SCServo SDK library + +# Control table address +ADDR_SCS_TORQUE_ENABLE = 40 +ADDR_STS_GOAL_ACC = 41 +ADDR_STS_GOAL_POSITION = 42 +ADDR_STS_GOAL_SPEED = 46 +ADDR_STS_PRESENT_POSITION = 56 + + +# Default setting +SCS1_ID = 1 # SCServo#1 ID : 1 +SCS2_ID = 2 # SCServo#1 ID : 2 +BAUDRATE = 1000000 # SCServo default baudrate : 1000000 +DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller + # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" + +SCS_MINIMUM_POSITION_VALUE = 100 # SCServo will rotate between this value +SCS_MAXIMUM_POSITION_VALUE = 4000 # and this value (note that the SCServo would not move when the position value is out of movable range. Check e-manual about the range of the SCServo you use.) +SCS_MOVING_STATUS_THRESHOLD = 20 # SCServo moving status threshold +SCS_MOVING_SPEED = 0 # SCServo moving speed +SCS_MOVING_ACC = 0 # SCServo moving acc +protocol_end = 0 # SCServo bit end(STS/SMS=0, SCS=1) + +index = 0 +scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position + + +# Initialize PortHandler instance +# Set the port path +# Get methods and members of PortHandlerLinux or PortHandlerWindows +portHandler = PortHandler(DEVICENAME) + +# Initialize PacketHandler instance +# Get methods and members of Protocol +packetHandler = PacketHandler(protocol_end) + +# Initialize GroupSyncWrite instance +groupSyncWrite = GroupSyncWrite(portHandler, packetHandler, ADDR_STS_GOAL_POSITION, 2) + +# 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() + +# SCServo#1 acc +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS1_ID, ADDR_STS_GOAL_ACC, SCS_MOVING_ACC) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# SCServo#2 acc +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS2_ID, ADDR_STS_GOAL_ACC, SCS_MOVING_ACC) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# SCServo#1 speed +scs_comm_result, scs_error = packetHandler.write2ByteTxRx(portHandler, SCS1_ID, ADDR_STS_GOAL_SPEED, SCS_MOVING_SPEED) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# SCServo#2 speed +scs_comm_result, scs_error = packetHandler.write2ByteTxRx(portHandler, SCS2_ID, ADDR_STS_GOAL_SPEED, SCS_MOVING_SPEED) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +while 1: + print("Press any key to continue! (or press ESC to quit!)") + if getch() == chr(0x1b): + break + + # Allocate goal position value into byte array + param_goal_position = [SCS_LOBYTE(scs_goal_position[index]), SCS_HIBYTE(scs_goal_position[index])] + + # Add SCServo#1 goal position value to the Syncwrite parameter storage + scs_addparam_result = groupSyncWrite.addParam(SCS1_ID, param_goal_position) + if scs_addparam_result != True: + print("[ID:%03d] groupSyncWrite addparam failed" % SCS1_ID) + quit() + + # Add SCServo#2 goal position value to the Syncwrite parameter storage + scs_addparam_result = groupSyncWrite.addParam(SCS2_ID, param_goal_position) + if scs_addparam_result != True: + print("[ID:%03d] groupSyncWrite addparam failed" % SCS2_ID) + quit() + + # Syncwrite goal position + scs_comm_result = groupSyncWrite.txPacket() + if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) + + # Clear syncwrite parameter storage + groupSyncWrite.clearParam() + + while 1: + # Read SCServo#1 present position + scs1_present_position_speed, scs_comm_result, scs_error = packetHandler.read4ByteTxRx(portHandler, SCS1_ID, ADDR_STS_PRESENT_POSITION) + if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) + elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + + # Read SCServo#2 present position + scs2_present_position_speed, scs_comm_result, scs_error = packetHandler.read4ByteTxRx(portHandler, SCS2_ID, ADDR_STS_PRESENT_POSITION) + if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) + elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + + scs1_present_position = SCS_LOWORD(scs1_present_position_speed) + scs1_present_speed = SCS_HIWORD(scs1_present_position_speed) + scs2_present_position = SCS_LOWORD(scs2_present_position_speed) + scs2_present_speed = SCS_HIWORD(scs2_present_position_speed) + print("[ID:%03d] GoalPos:%03d PresPos:%03d PresSpd:%03d\t[ID:%03d] GoalPos:%03d PresPos:%03d PresSpd:%03d" + % (SCS1_ID, scs_goal_position[index], scs1_present_position, SCS_TOHOST(scs1_present_speed, 15), + SCS2_ID, scs_goal_position[index], scs2_present_position, SCS_TOHOST(scs2_present_speed, 15))) + + if not ((abs(scs_goal_position[index] - scs1_present_position) > SCS_MOVING_STATUS_THRESHOLD) and (abs(scs_goal_position[index] - scs2_present_position) > SCS_MOVING_STATUS_THRESHOLD)): + break + + # Change goal position + if index == 0: + index = 1 + else: + index = 0 + +# SCServo#1 torque +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS1_ID, ADDR_SCS_TORQUE_ENABLE, 0) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# SCServo#2 torque +scs_comm_result, scs_error = packetHandler.write1ByteTxRx(portHandler, SCS2_ID, ADDR_SCS_TORQUE_ENABLE, 0) +if scs_comm_result != COMM_SUCCESS: + print("%s" % packetHandler.getTxRxResult(scs_comm_result)) +elif scs_error != 0: + print("%s" % packetHandler.getRxPacketError(scs_error)) + +# Close port +portHandler.closePort() \ No newline at end of file diff --git a/scsservo_sdk_source/SCServo_Python_200831.7z b/scsservo_sdk_source/SCServo_Python_200831.7z new file mode 100644 index 0000000000000000000000000000000000000000..93d0012fc9e001cffaeace5c7f0626e246ae3f1d GIT binary patch literal 40391 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 HgNpzF+v(F6 literal 0 HcmV?d00001 diff --git a/scsservo_sdk_source/SCServo_Python_220415.7z b/scsservo_sdk_source/SCServo_Python_220415.7z deleted file mode 100644 index 3ddb9a02fc676f7aa17be651bd73cedbc76cefb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8755 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 diff --git a/setup.py b/setup.py index 9db2850..bdc3a33 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='feetech-servo-sdk', - version='0.1.0', + version='0.2.0', packages=['scservo_sdk'], url='https://github.com/Adam-Software/FEETECH-Servo-Python-SDK', license='UNLICENSE', diff --git a/sms_sts/ping.py b/sms_sts/ping.py deleted file mode 100644 index 12783f9..0000000 --- a/sms_sts/ping.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python -# -# ********* Ping Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) -# 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() - -# Try to ping the SCServo -# Get SCServo model number -scs_model_number, scs_comm_result, scs_error = packetHandler.ping(SCS_ID) -if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) -else: - print("[ID:%03d] ping Succeeded. SCServo model number : %d" % (SCS_ID, scs_model_number)) -if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - -# Close port -portHandler.closePort() diff --git a/sms_sts/read.py b/sms_sts/read.py deleted file mode 100644 index 9a4219b..0000000 --- a/sms_sts/read.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - # Read SCServo present position - scs_present_position, scs_present_speed, scs_comm_result, scs_error = packetHandler.ReadPosSpeed(SCS_ID) - if scs_comm_result != COMM_SUCCESS: - print(packetHandler.getTxRxResult(scs_comm_result)) - else: - print("[ID:%03d] PresPos:%d PresSpd:%d" % (SCS_ID, scs_present_position, scs_present_speed)) - if scs_error != 0: - print(packetHandler.getRxPacketError(scs_error)) - -# Close port -portHandler.closePort() diff --git a/sms_sts/read_write.py b/sms_sts/read_write.py deleted file mode 100644 index 7cde457..0000000 --- a/sms_sts/read_write.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" -SCS_MINIMUM_POSITION_VALUE = 0 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 4095 -SCS_MOVING_SPEED = 2400 # SCServo moving speed -SCS_MOVING_ACC = 50 # SCServo moving acc - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - # Write SCServo goal position/moving speed/moving acc - scs_comm_result, scs_error = packetHandler.WritePosEx(SCS_ID, scs_goal_position[index], SCS_MOVING_SPEED, SCS_MOVING_ACC) - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - elif scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - - while 1: - # Read SCServo present position - scs_present_position, scs_present_speed, scs_comm_result, scs_error = packetHandler.ReadPosSpeed(SCS_ID) - if scs_comm_result != COMM_SUCCESS: - print(packetHandler.getTxRxResult(scs_comm_result)) - else: - print("[ID:%03d] GoalPos:%d PresPos:%d PresSpd:%d" % (SCS_ID, scs_goal_position[index], scs_present_position, scs_present_speed)) - if scs_error != 0: - print(packetHandler.getRxPacketError(scs_error)) - - # Read SCServo moving status - moving, scs_comm_result, scs_error = packetHandler.ReadMoving(SCS_ID) - if scs_comm_result != COMM_SUCCESS: - print(packetHandler.getTxRxResult(scs_comm_result)) - - if moving==0: - break - - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort() diff --git a/sms_sts/reg_write.py b/sms_sts/reg_write.py deleted file mode 100644 index 4535b97..0000000 --- a/sms_sts/reg_write.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" -SCS_MINIMUM_POSITION_VALUE = 0 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 4095 -SCS_MOVING_SPEED = 2400 # SCServo moving speed -SCS_MOVING_ACC = 50 # SCServo moving acc - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - # Write SCServo goal position/moving speed/moving acc - for scs_id in range(1, 11): - scs_comm_result, scs_error = packetHandler.RegWritePosEx(scs_id, scs_goal_position[index], SCS_MOVING_SPEED, SCS_MOVING_ACC) - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - packetHandler.RegAction() - - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort() diff --git a/sms_sts/sync_read.py b/sms_sts/sync_read.py deleted file mode 100644 index 47a88f0..0000000 --- a/sms_sts/sync_read.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python -# -# ********* Sync Read Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) - -# 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() - -groupSyncRead = GroupSyncRead(packetHandler, SMS_STS_PRESENT_POSITION_L, 4) - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - for scs_id in range(1, 11): - # Add parameter storage for SCServo#1~10 present position value - scs_addparam_result = groupSyncRead.addParam(scs_id) - if scs_addparam_result != True: - print("[ID:%03d] groupSyncRead addparam failed" % scs_id) - - scs_comm_result = groupSyncRead.txRxPacket() - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - - for scs_id in range(1, 11): - # Check if groupsyncread data of SCServo#1~10 is available - scs_data_result, scs_error = groupSyncRead.isAvailable(scs_id, SMS_STS_PRESENT_POSITION_L, 4) - if scs_data_result == True: - # Get SCServo#scs_id present position value - scs_present_position = groupSyncRead.getData(scs_id, SMS_STS_PRESENT_POSITION_L, 2) - scs_present_speed = groupSyncRead.getData(scs_id, SMS_STS_PRESENT_SPEED_L, 2) - print("[ID:%03d] PresPos:%d PresSpd:%d" % (scs_id, scs_present_position, packetHandler.scs_tohost(scs_present_speed, 15))) - else: - print("[ID:%03d] groupSyncRead getdata failed" % scs_id) - continue - if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - groupSyncRead.clearParam() -# Close port -portHandler.closePort() diff --git a/sms_sts/sync_read_write.py b/sms_sts/sync_read_write.py deleted file mode 100644 index 86a24b4..0000000 --- a/sms_sts/sync_read_write.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python -# -# ********* Sync Read and Sync Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os -import time - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Control table address - -# Default setting -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" - -SCS_MINIMUM_POSITION_VALUE = 0 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 4095 -SCS_MOVING_SPEED = 2400 # SCServo moving speed -SCS_MOVING_ACC = 50 # SCServo moving acc - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) - -# 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() - -groupSyncRead = GroupSyncRead(packetHandler, SMS_STS_PRESENT_POSITION_L, 11) - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - for scs_id in range(1, 11): - # Add SCServo#1~10 goal position\moving speed\moving accc value to the Syncwrite parameter storage - scs_addparam_result = packetHandler.SyncWritePosEx(scs_id, scs_goal_position[index], SCS_MOVING_SPEED, SCS_MOVING_ACC) - if scs_addparam_result != True: - print("[ID:%03d] groupSyncWrite addparam failed" % scs_id) - - # Syncwrite goal position - scs_comm_result = packetHandler.groupSyncWrite.txPacket() - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - - # Clear syncwrite parameter storage - packetHandler.groupSyncWrite.clearParam() - time.sleep(0.002) #wait for servo status moving=1 - while 1: - # Add parameter storage for SCServo#1~10 present position value - for scs_id in range(1, 11): - scs_addparam_result = groupSyncRead.addParam(scs_id) - if scs_addparam_result != True: - print("[ID:%03d] groupSyncRead addparam failed" % scs_id) - - scs_comm_result = groupSyncRead.txRxPacket() - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - - scs_last_moving = 0; - for scs_id in range(1, 11): - # Check if groupsyncread data of SCServo#1~10 is available - scs_data_result, scs_error = groupSyncRead.isAvailable(scs_id, SMS_STS_PRESENT_POSITION_L, 11) - if scs_data_result == True: - # Get SCServo#scs_id present position moving value - scs_present_position = groupSyncRead.getData(scs_id, SMS_STS_PRESENT_POSITION_L, 2) - scs_present_speed = groupSyncRead.getData(scs_id, SMS_STS_PRESENT_SPEED_L, 2) - scs_present_moving = groupSyncRead.getData(scs_id, SMS_STS_MOVING, 1) - # print(scs_present_moving) - print("[ID:%03d] PresPos:%d PresSpd:%d" % (scs_id, scs_present_position, packetHandler.scs_tohost(scs_present_speed, 15))) - if scs_present_moving==1: - scs_last_moving = 1; - else: - print("[ID:%03d] groupSyncRead getdata failed" % scs_id) - continue - if scs_error: - print(packetHandler.getRxPacketError(scs_error)) - print("---") - - # Clear syncread parameter storage - groupSyncRead.clearParam() - if scs_last_moving==0: - break - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort() diff --git a/sms_sts/sync_write.py b/sms_sts/sync_write.py deleted file mode 100644 index bfb4805..0000000 --- a/sms_sts/sync_write.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python -# -# ********* Sync Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" - -SCS_MINIMUM_POSITION_VALUE = 0 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 4095 -SCS_MOVING_SPEED = 2400 # SCServo moving speed -SCS_MOVING_ACC = 50 # SCServo moving acc - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - for scs_id in range(1, 11): - # Add SCServo#1~10 goal position\moving speed\moving accc value to the Syncwrite parameter storage - scs_addparam_result = packetHandler.SyncWritePosEx(scs_id, scs_goal_position[index], SCS_MOVING_SPEED, SCS_MOVING_ACC) - if scs_addparam_result != True: - print("[ID:%03d] groupSyncWrite addparam failed" % scs_id) - - # Syncwrite goal position - scs_comm_result = packetHandler.groupSyncWrite.txPacket() - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - - # Clear syncwrite parameter storage - packetHandler.groupSyncWrite.clearParam() - - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort() diff --git a/sms_sts/wheel.py b/sms_sts/wheel.py deleted file mode 100644 index fdbf030..0000000 --- a/sms_sts/wheel.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" -SCS_MOVING_SPEED0 = 2400 # SCServo moving speed -SCS_MOVING_SPEED1 = -2400 # SCServo moving speed -SCS_MOVING_ACC = 50 # SCServo moving acc - -index = 0 -scs_move_speed = [SCS_MOVING_SPEED0, 0, SCS_MOVING_SPEED1, 0] - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) - -# 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() - -scs_comm_result, scs_error = packetHandler.WheelMode(SCS_ID) -if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) -elif scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - # Write SCServo goal position/moving speed/moving acc - scs_comm_result, scs_error = packetHandler.WriteSpec(SCS_ID, scs_move_speed[index], SCS_MOVING_ACC) - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - - # Change move speed - index += 1 - if index == 4: - index = 0 - -# Close port -portHandler.closePort() diff --git a/sms_sts/write.py b/sms_sts/write.py deleted file mode 100644 index e0c239a..0000000 --- a/sms_sts/write.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python -# -# ********* Gen Write Example ********* -# -# -# Available SCServo model on this example : All models using Protocol SCS -# This example is tested with a SCServo(STS/SMS), and an URT -# - -import sys -import os - -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 - -sys.path.append("..") -from scservo_sdk import * # Uses SCServo SDK library - -# Default setting -SCS_ID = 1 # SCServo ID : 1 -BAUDRATE = 1000000 # SCServo default baudrate : 1000000 -DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller - # ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*" -SCS_MINIMUM_POSITION_VALUE = 0 # SCServo will rotate between this value -SCS_MAXIMUM_POSITION_VALUE = 4095 -SCS_MOVING_SPEED = 2400 # SCServo moving speed -SCS_MOVING_ACC = 50 # SCServo moving acc - -index = 0 -scs_goal_position = [SCS_MINIMUM_POSITION_VALUE, SCS_MAXIMUM_POSITION_VALUE] # Goal position - -# Initialize PortHandler instance -# Set the port path -# Get methods and members of PortHandlerLinux or PortHandlerWindows -portHandler = PortHandler(DEVICENAME) - -# Initialize PacketHandler instance -# Get methods and members of Protocol -packetHandler = sms_sts(portHandler) - -# 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() - -while 1: - print("Press any key to continue! (or press ESC to quit!)") - if getch() == chr(0x1b): - break - - # Write SCServo goal position/moving speed/moving acc - scs_comm_result, scs_error = packetHandler.WritePosEx(SCS_ID, scs_goal_position[index], SCS_MOVING_SPEED, SCS_MOVING_ACC) - if scs_comm_result != COMM_SUCCESS: - print("%s" % packetHandler.getTxRxResult(scs_comm_result)) - if scs_error != 0: - print("%s" % packetHandler.getRxPacketError(scs_error)) - - # Change goal position - if index == 0: - index = 1 - else: - index = 0 - -# Close port -portHandler.closePort()