# Program automatically generated by RoboDK using the post processor for uFactory uArm robots
# Run this file with Python to run the program on the robot
# 
# Make sure the xArm Python library is installed or available in the path
import sys
import math

sys.path.insert(0,"C:/RoboDK/Python")
# Import the xArm library
from xarm.wrapper import XArmAPI

def print_message(arg):
    print(arg)

def print_joints(arg1, arg2):
    print(arg1)

def UpdateStatus(arg):
    pass

DRIVER_VERSION = 'RoboDK Driver for xArm v1.1.4'

ROBOTCOM_UNKNOWN = -1000
ROBOTCOM_CONNECTION_PROBLEMS = -3
ROBOTCOM_DISCONNECTED = -2
ROBOTCOM_NOT_CONNECTED = -1
ROBOTCOM_READY = 0
ROBOTCOM_WORKING = 1
ROBOTCOM_WAITING = 2
nDOFs_MIN = 6


class ComRobot:
    """Robot class for programming xArm robots"""
    LAST_MSG = None  # Keep a copy of the last message received
    CONNECTED = False  # Connection status is known at all times
    UARMAPI = None  #XArmAPI("127.0.0.1")
    BUFFER_SIZE = None
    TIMEOUT = None
    #Speed and accelerations
    LINEARSPEED = 100
    LINEARACELL = 30
    JOINTSPEED = 50
    JOINTACELL = 80
    LAST_TARGET_JOINTS = []

    # This is executed when the object is created
    def __init__(self):
        self.BUFFER_SIZE = 512  # bytes
        #self.TIMEOUT = 5 * 60  # seconds: it must be enough time for a movement to complete
        self.TIMEOUT = 10  # seconds

        # destructor

    def __del__(self):
        self.disconnect()

    # Disconnect from robot
    def disconnect(self):
        self.CONNECTED = False
        if self.UARMAPI:
            try:
                self.UARMAPI.disconnect()
            except OSError:
                return False
        return True

    # Connect to robot
    def connect(self, ip, port=-1):
        global ROBOT_MOVING
        self.disconnect()
        #print_message('Connecting to robot %s:%i' % (ip, port))
        print_message(DRIVER_VERSION)
        print_message('Connecting to robot IP %s' % (ip))
        # Create new socket connection
        UpdateStatus(ROBOTCOM_WORKING)
        try:
            import time
            self.UARMAPI = XArmAPI(ip, do_not_open=False)
            self.UARMAPI.motion_enable(enable=True)
            self.UARMAPI.clean_error()
            time.sleep(0.01)
            self.UARMAPI.set_mode(0)
            time.sleep(0.01)
            self.UARMAPI.set_state(state=0)
            time.sleep(0.01)
            self.UARMAPI.motion_enable(True)

            self.LAST_TARGET_JOINTS = self.UARMAPI.angles
            #self.UARMAPI.reset(wait=True)
            #self.UARMAPI.register_report_callback(self.monitoringCallback, report_cartesian=False, report_joints=True,
            #                            report_state=False, report_error_code=False, report_warn_code=False,
            #                            report_mtable=False, report_mtbrake=False, report_cmd_num=False)
        except Exception as e:
            print_message(str(e))
            return False

        version = self.UARMAPI.version
        print_message("API Version:" + str(version))

        self.CONNECTED = True
        ROBOT_MOVING = False

        sys.stdout.flush()
        return True

    def joints_error(self, j1, j2):
        if j1 is None or j2 is None:
            return 1e6

        if type(j2) is list and type(j2[0]) is str:
            j2 = [float(x) for x in j2]

        error = -1
        nj = min(len(j1), len(j2))
        for i in range(nj):
            error = max(error, abs(j1[i] - j2[i]))

        return error

    def recv_acknowledge(self):
        done = False
        startState = self.UARMAPI.state
        endState = 0
        while done == False:

            #cartesianPosition = self.UARMAPI.get_position(is_radian=False)
            jointPosition = self.UARMAPI.angles
            print_joints(jointPosition, True)

            #if self.joints_error(self.UARMAPI.angles,self.LAST_TARGET_JOINTS) < 4.0:
            #    done = True
            curState = self.UARMAPI.state
            if (curState != 1) and (curState != 4):
                endState = curState
                done = True

            if self.UARMAPI.connected != True:
                return False

            if self.UARMAPI.has_error == True:
                print_message("Error code:" + str(self.UARMAPI.error_code))
                self.UARMAPI.clean_error()
                return False

            if self.UARMAPI.has_warn == True:
                print_message("Warning code:" + str(self.UARMAPI.warn_code))
                self.UARMAPI.clean_warn()
                return False

        jointPosition = self.UARMAPI.angles
        print_joints(jointPosition, True)

        return True

    def MoveJ(self, joints_xyzwpr):
        global nDOFs_MIN
        joints = joints_xyzwpr[:nDOFs_MIN]
        xyzwpr = joints_xyzwpr[nDOFs_MIN:]

        jointsRad = [round(x * (math.pi / 180), 6) for x in joints[:6]] + [0]  # 6 DOF + 1 null
        try:
            #self.UARMAPI.set_mode(mode=1) #Mode 1 corresponds to moving this breaks it
            self.UARMAPI.set_state(state=0)
            self.UARMAPI.motion_enable(True)
            self.UARMAPI.set_servo_angle(angle=joints, mvacc=self.JOINTACELL, speed=self.JOINTSPEED, is_radian=False, wait=False)
            import time
            if self.UARMAPI.state == 2:
                time.sleep(0.01)
            self.LAST_TARGET_JOINTS = joints
        except Exception as e:
            print_message(str(e))
            return False
        return True

    def MoveL(self, joints_xyzwpr):
        global nDOFs_MIN
        joints = joints_xyzwpr[:nDOFs_MIN]
        joints.insert(0, 0)
        xyzwpr = joints_xyzwpr[nDOFs_MIN:]
        try:
            #self.UARMAPI.set_mode(mode=1) #Mode 1 corresponds to moving
            self.UARMAPI.set_state(state=0)
            self.UARMAPI.motion_enable(True)
            #xArmPose = self.UARMAPI.get_forward_kinematics(tuple(joints),input_is_radian=False,return_is_radian=False)[1]
            self.UARMAPI.set_position_aa(axis_angle_pose=xyzwpr, mvacc=self.LINEARACELL, speed=self.LINEARSPEED, is_radian=False, wait=False)
            import time
            if self.UARMAPI.state == 2:
                time.sleep(0.01)
            self.LAST_TARGET_JOINTS = joints
        except Exception as e:
            print_message(str(e))
            return False
        return True

    def MoveC(self, joints):
        try:
            self.UARMAPI.set_mode(mode=1)  #Mode 1 corresponds to moving
            self.UARMAPI.motion_enable(True)
            self.UARMAPI.move_circle(pose1=joints[0:6], pose2=joints[7:], percent=50, speed=self.JOINTSPEED, mvacc=self.JOINTACELL, wait=True)
            self.LAST_TARGET_JOINTS = joints
        except Exception as e:
            print_message(str(e))
            return False
        return True

    def getJoints(self):
        if (self.UARMAPI.default_is_radian == True):
            jointPosition = self.UARMAPI.angles
            for i in range(0, len(jointPosition)):
                jointPosition[i] = math.degrees(jointPosition[i])
        else:
            #cartesianPosition = self.UARMAPI.get_position(is_radian=False)
            jointPosition = self.UARMAPI.angles
        return jointPosition

    def setSpeed(self, speed_values):
        # speed_values[0] = speed_values[0] # linear speed in mm/s
        # speed_values[1] = speed_values[1] # joint speed in mm/s
        # speed_values[2] = speed_values[2] # linear acceleration in mm/s2
        # speed_values[3] = speed_values[3] # joint acceleration in deg/s2
        if (speed_values[0] != -1):
            self.LINEARSPEED = speed_values[0]

        if (speed_values[1] != -1):
            self.JOINTSPEED = speed_values[1]

        if (speed_values[2] != -1):
            self.LINEARACELL = speed_values[2]

        if (speed_values[3] != -1):
            self.JOINTACELL = speed_values[3]

        return True

    def setTool(self, tool_pose):
        self.UARMAPI.set_tcp_offset(tool_pose)
        return True

    def Pause(self, timeMS):
        import time
        time.sleep(timeMS / 1000)
        return True

    def setRounding(self, rounding):
        self.UARMAPI.set_tcp_jerk(rounding)
        return True

    def setDO(self, digital_IO_State):
        self.UARMAPI.set_cgpio_digital_output_function(digital_IO_State[0], digital_IO_State[1])
        return True

    def WaitDI(self, digital_IO_Num):
        import time
        start = time.time()
        ioNumber = digital_IO_Num[0]
        ioState = self.UARMAPI.get_tgpio_digital(ioNumber)
        desiredState = digital_IO_Num[1]
        try:
            timeout = digital_IO_Num[2]
        except Exception as e:
            e = e
            timeout = 0

        while not (ioState == desiredState) and (time.time() - start) < timeout:
            ioState = self.UARMAPI.get_tgpio_digital(ioNumber)
            time.sleep(0.1)
        return True

    #def SendCmd(self, cmd, values=None):
    #    """Send a command. Returns True if success, False otherwise."""
    #    # print('SendCmd(cmd=' + str(cmd) + ', values=' + str(values) if values else '' + ')')
    #    # Skip the command if the robot is not connected
    #    if not self.CONNECTED:
    #        UpdateStatus(ROBOTCOM_NOT_CONNECTED)
    #        return False
    #
    #    if not self.send_int(cmd):
    #        print_message("Robot connection broken")
    #        UpdateStatus(ROBOTCOM_NOT_CONNECTED)
    #        return False
    #
    #    if values is None:
    #        return True
    #    elif not isinstance(values, list):
    #        values = [values]
    #
    #    if not self.send_array(values):
    #        print_message("Robot connection broken")
    #        UpdateStatus(ROBOTCOM_NOT_CONNECTED)
    #        return False
    #
    #    return True


def ConnectRobot():
    # Connect to the robot
    global robot
    ROBOT_IP   = "192.168.1.156"
    robot = ComRobot()
    while not robot.connect(ROBOT_IP):
        print_message("Retrying connection...")
        import time
        time.sleep(0.5)

    print_message("Connected to robot: " + ROBOT_IP)



# Program Start: RhinoProject
def RhinoProject():
    global robot
    # Generating program: RhinoProject

    #Program generated by RoboDK v5.6.4 for uFactory Lite6 on 02/10/2023 16:48:12
    #Using nominal kinematics.
    robot.setRounding(1.000)
    robot.setSpeed([1000.0,-1,-1,-1])
    #robot ref frame set to 200.000, 100.000, 100.000,  -0.000, 0.000, -0.000
    robot.setTool([0.000, 0.000, 50.000,  -0.000, 0.000, -0.000])

    #Show BRL
    robot.MoveJ([17.534400,47.486400,100.638000,0.000000,53.151400,-162.466000])
    robot.MoveJ([17.534400,60.966500,98.129500,0.000000,37.163000,-162.466000])
    #robot.MoveJ([17.534400,60.966500,98.129500,0.000000,37.163000,-162.466000,163.839, 14.958, 0.000,  -180.000, -0.000, 180.000])
    
    robot.setSpeed([50.0,-1,-1,-1])
    robot.MoveJ([18.434600,62.298300,100.588000,0.000000,38.290000,-161.565000])
    robot.MoveJ([19.370800,63.552600,102.905000,0.000000,39.352000,-160.629000])
    robot.MoveJ([20.338300,64.715900,105.053000,0.000000,40.337200,-159.662000])
    robot.MoveJ([21.332800,65.773500,107.007000,0.000000,41.233000,-158.667000])
    robot.MoveJ([22.350200,66.710300,108.737000,0.000000,42.026600,-157.650000])
    robot.MoveJ([23.386400,67.510800,110.216000,0.000000,42.704700,-156.614000])
    robot.MoveJ([24.437700,68.160400,111.415000,0.000000,43.254900,-155.562000])
    robot.MoveJ([25.500400,68.645800,112.312000,0.000000,43.666000,-154.500000])
    #,166.640, 74.881, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([26.570800,68.956100,112.885000,0.000000,43.928700,-153.429000])
    #,164.086, 82.088, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([27.645400,69.084000,113.121000,0.000000,44.037100,-152.355000])
    #,160.921, 89.049, 0.000,  180.000, 0.000, 180.000])
    robot.MoveJ([28.720700,69.026400,113.015000,0.000000,43.988300,-151.279000])
    #,157.170, 95.712, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([29.793100,68.784700,112.568000,0.000000,43.783700,-150.207000])
    #,152.860, 102.028, 0.000,  180.000, 0.000, 180.000])
    robot.MoveJ([30.859200,68.364800,111.793000,0.000000,43.428000,-149.141000])
    #,148.023, 107.950, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([31.915200,67.776200,110.706000,0.000000,42.929500,-148.085000])
    #,142.694, 113.435, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([32.957600,67.031300,109.330000,0.000000,42.298500,-147.042000])
    #,136.914, 118.441, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([33.982600,66.144500,107.692000,0.000000,41.547300,-146.017000])
    #,130.726, 122.931, 0.000,  180.000, -0.000, -180.000])
    robot.MoveJ([34.986300,65.130900,105.820000,0.000000,40.688800,-145.014000])
    #,124.173, 126.873, 0.000,  180.000, 0.000, 180.000])
    robot.MoveJ([35.964600,64.006100,103.742000,0.000000,39.736000,-144.035000])
    #,117.307, 130.237, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([36.913200,62.784700,101.486000,0.000000,38.701800,-143.087000])
    #,110.176, 132.999, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([37.827600,61.480800,99.078900,0.000000,37.598100,-142.172000])
    #,102.835, 135.137, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([38.703100,60.107300,96.543700,0.000000,36.436300,-141.297000])
    #,95.337, 136.636, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([39.534600,58.676300,93.903100,0.000000,35.226800,-140.465000])
    #,87.738, 137.485, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([40.316700,57.198400,91.177500,0.000000,33.979000,-139.683000])
    #,80.094, 137.677, 0.000,  180.000, -0.000, -180.000])
    robot.MoveJ([41.043700,55.683700,88.385600,0.000000,32.701900,-138.956000])
    #,72.462, 137.212, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([41.709300,54.141300,85.544800,0.000000,31.403500,-138.291000])
    #,64.897, 136.092, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([42.307100,52.579500,82.671000,0.000000,30.091500,-137.693000])
    #,57.458, 134.327, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([42.829900,51.006400,79.779400,0.000000,28.773100,-137.170000])
    #,50.197, 131.928, 0.000,  180.000, -0.000, -180.000])
    robot.MoveJ([43.270300,49.429400,76.884500,0.000000,27.455100,-136.730000])
    #,43.170, 128.914, 0.000,  180.000, 0.000, 180.000])
    robot.MoveJ([43.620300,47.855900,74.000100,0.000000,26.144200,-136.380000])
    #,36.428, 125.307, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([43.871600,46.293200,71.140100,0.000000,24.846900,-136.128000])
    #,30.020, 121.134, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([44.015200,44.748600,68.318300,0.000000,23.569800,-135.985000])
    #,23.996, 116.425, 0.000,  180.000, -0.000, -180.000])
    robot.MoveJ([44.042300,43.229300,65.548700,0.000000,22.319400,-135.958000])
    #,18.398, 111.216, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([43.943500,41.743300,62.845700,0.000000,21.102400,-136.056000])
    #,13.269, 105.545, 0.000,  180.000, 0.000, 180.000])
    robot.MoveJ([43.709700,40.298500,60.224200,0.000000,19.925700,-136.290000])
    #,8.646, 99.454, 0.000,  180.000, 0.000, 180.000])
    robot.MoveJ([43.332200,38.903500,57.699700,0.000000,18.796300,-136.668000])
    #,4.564, 92.989, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([42.802900,37.567200,55.288600,0.000000,17.721400,-137.197000])
    #,1.053, 86.196, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([42.115000,36.299500,53.007900,0.000000,16.708400,-137.885000])
    #,-1.861, 79.127, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([41.263700,35.110300,50.875200,0.000000,15.764900,-138.736000])
    #,-4.156, 71.833, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([40.246600,34.010300,48.908800,0.000000,14.898400,-139.753000])
    #,-5.817, 64.369, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([39.064900,33.010600,47.127100,0.000000,14.116600,-140.935000])
    #,-6.829, 56.790, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([37.723800,32.122100,45.548700,0.000000,13.426600,-142.276000])
    #,-7.186, 49.152, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([36.233300,31.355800,44.191200,0.000000,12.835400,-143.767000])
    #,-6.885, 41.511, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([34.608700,30.721900,43.071300,0.000000,12.349400,-145.391000])
    #,-5.928, 33.925, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([32.871000,30.229600,42.203500,0.000000,11.973800,-147.129000])
    #,-4.323, 26.449, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([31.046100,29.886600,41.599800,0.000000,11.713200,-148.954000])
    #,-2.081, 19.138, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([29.164100,29.698500,41.269000,0.000000,11.570500,-150.836000])
    #,0.781, 12.048, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([27.258400,29.668300,41.216000,0.000000,11.547700,-152.742000])
    #,4.242, 5.229, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([25.363400,29.796700,41.441600,0.000000,11.645000,-154.637000])
    #,8.276, -1.266, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([23.513100,30.081400,41.942500,0.000000,11.861100,-156.487000])
    #,12.854, -7.391, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([21.738900,30.517700,42.711100,0.000000,12.193400,-158.261000])
    #,17.942, -13.099, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([20.068600,31.098800,43.736900,0.000000,12.638100,-159.931000])
    #,23.501, -18.349, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([18.525100,31.816000,45.006000,0.000000,13.190000,-161.475000])
    #,29.491, -23.102, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([17.125700,32.659300,46.502500,0.000000,13.843200,-162.874000])
    #,35.867, -27.322, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([15.882600,33.618100,48.209100,0.000000,14.591000,-164.117000])
    #,42.583, -30.978, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([14.802600,34.681300,50.107500,0.000000,15.426200,-165.197000])
    #,49.588, -34.044, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([13.888500,35.837900,52.179200,0.000000,16.341300,-166.112000])
    #,56.831, -36.496, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([13.138900,37.077000,54.405800,0.000000,17.328800,-166.861000])
    #,64.257, -38.316, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([12.550100,38.388400,56.769400,0.000000,18.381100,-167.450000])
    #,71.813, -39.491, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([12.115800,39.762100,59.252800,0.000000,19.490600,-167.884000])
    #,79.441, -40.013, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([11.828400,41.189100,61.839300,0.000000,20.650200,-168.172000])
    #,87.087, -39.876, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([11.679400,42.660400,64.513100,0.000000,21.852700,-168.321000])
    #,94.692, -39.083, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([11.659700,44.168000,67.259200,0.000000,23.091200,-168.340000])
    #,102.201, -37.639, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([11.760200,45.703900,70.062800,0.000000,24.358900,-168.240000])
    #,109.558, -35.555, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([11.971600,47.260600,72.909900,0.000000,25.649300,-168.028000])
    #,116.708, -32.846, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([12.285100,48.830800,75.786600,0.000000,26.955800,-167.715000])
    #,123.599, -29.532, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([12.692100,50.407300,78.679200,0.000000,28.271900,-167.308000])
    #,130.180, -25.639, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([13.184500,51.982800,81.573800,0.000000,29.591000,-166.815000])
    #,136.402, -21.194, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([13.754700,53.549800,84.456000,0.000000,30.906300,-166.245000])
    #,142.218, -16.230, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([14.395300,55.100500,87.311200,0.000000,32.210700,-165.605000])
    #,147.587, -10.785, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([15.099700,56.626800,90.123600,0.000000,33.496800,-164.900000])
    #,152.467, -4.899, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([15.861600,58.119800,92.876500,0.000000,34.756800,-164.138000])
    #,156.824, 1.385, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveJ([16.675000,59.569800,95.551700,0.000000,35.981900,-163.325000])
    #,160.624, 8.021, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveJ([17.534400,60.966500,98.129500,0.000000,37.163000,-162.466000])
    #,163.839, 14.958, 0.000,  -180.000, -0.000, 180.000])
    robot.setSpeed([1000.0,-1,-1,-1])
    robot.MoveJ([17.534400,47.486400,100.638000,0.000000,53.151400,-162.466000])
    #,163.839, 14.958, 100.000,  -180.000, -0.000, 180.000])
    return

if __name__ == "__main__":
    # Connect to the robot and run the program
    ConnectRobot()
    RhinoProject()
