# 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
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 17:40:08
    #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.MoveL([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.MoveL([18.434600,62.298300,100.588000,0.000000,38.290000,-161.565000,166.446, 22.146, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveL([19.370800,63.552600,102.905000,0.000000,39.352000,-160.629000,168.426, 29.532, 0.000,  -180.000, 0.000, -180.000])
    robot.MoveL([20.338300,64.715900,105.053000,0.000000,40.337200,-159.662000,169.763, 37.061, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveL([21.332800,65.773500,107.007000,0.000000,41.233000,-158.667000,170.449, 44.676, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveL([22.350200,66.710300,108.737000,0.000000,42.026600,-157.650000,170.477, 52.323, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveL([23.386400,67.510800,110.216000,0.000000,42.704700,-156.614000,169.847, 59.943, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveL([24.437700,68.160400,111.415000,0.000000,43.254900,-155.562000,168.565, 67.481, 0.000,  -180.000, -0.000, 180.000])
    robot.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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.MoveL([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()
