From 1604eb5c7d37a353ac9a4d12b7ecb9aba8e8c2d7 Mon Sep 17 00:00:00 2001 From: ipa-fxm <felix.messmer@ipa.fhg.de> Date: Thu, 25 Sep 2014 14:50:22 +0000 Subject: [PATCH] add URConnectionRT to driver --- ur_driver/src/ur_driver/driver.py | 225 ++++++++++++++++++++++-------- 1 file changed, 167 insertions(+), 58 deletions(-) diff --git a/ur_driver/src/ur_driver/driver.py b/ur_driver/src/ur_driver/driver.py index e23199d..2410798 100755 --- a/ur_driver/src/ur_driver/driver.py +++ b/ur_driver/src/ur_driver/driver.py @@ -17,6 +17,7 @@ from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint from geometry_msgs.msg import WrenchStamped from ur_driver.deserialize import RobotState, RobotMode +from ur_driver.deserializeRT import RobotStateRT from ur_msgs.srv import SetPayload, SetIO from ur_msgs.msg import * @@ -36,6 +37,7 @@ prevent_programming = False joint_offsets = {} PORT=30002 +RT_PORT=30003 DEFAULT_REVERSE_PORT = 50001 MSG_OUT = 1 @@ -58,6 +60,7 @@ MULT_jointstate = 10000.0 MULT_time = 1000000.0 MULT_blend = 1000.0 MULT_analog = 1000000.0 +MULT_analog_robotstate = 0.1 #Bounds for SetPayload service MIN_PAYLOAD = 0.0 @@ -83,9 +86,12 @@ Q3 = [1.5,-0.2,-1.57,0,0,0] connected_robot = None connected_robot_lock = threading.Lock() connected_robot_cond = threading.Condition(connected_robot_lock) -pub_joint_states = rospy.Publisher('joint_states', JointState, queue_size=1) -pub_wrench = rospy.Publisher('wrench', WrenchStamped, queue_size=1) -pub_io_states = rospy.Publisher('io_states', IOStates, queue_size=1) +pub_joint_states = rospy.Publisher('joint_states', JointState) +pub_joint_statesRT = rospy.Publisher('joint_statesRT', JointState) +pub_robot_stateRT = rospy.Publisher('robot_stateRT', RobotStateRTMsg) +pub_wrench = rospy.Publisher('wrench', WrenchStamped) +pub_io_states = rospy.Publisher('io_states', IOStates) +pub_io_states2 = rospy.Publisher('io_states2', IOStates) #dump_state = open('dump_state', 'wb') class EOF(Exception): pass @@ -202,6 +208,36 @@ class URConnection(object): msg.effort = [0]*6 pub_joint_states.publish(msg) self.last_joint_states = msg + + # Use information from the robot state packet to publish IOStates + msg = IOStates() + #gets digital in states + for i in range(0, 10): + msg.digital_in_states.append(DigitalIn(i, (state.masterboard_data.digital_input_bits & (1<<i))>>i)) + #gets digital out states + for i in range(0, 10): + msg.digital_out_states.append(DigitalOut(i, (state.masterboard_data.digital_output_bits & (1<<i))>>i)) + #gets analog_in[0] state + inp = state.masterboard_data.analog_input0 / MULT_analog_robotstate + msg.analog_in_states.append(Analog(0, inp)) + #gets analog_in[1] state + inp = state.masterboard_data.analog_input1 / MULT_analog_robotstate + msg.analog_in_states.append(Analog(1, inp)) + #gets analog_out[0] state + inp = state.masterboard_data.analog_output0 / MULT_analog_robotstate + msg.analog_out_states.append(Analog(0, inp)) + #gets analog_out[1] state + inp = state.masterboard_data.analog_output1 / MULT_analog_robotstate + msg.analog_out_states.append(Analog(1, inp)) + #print "Publish IO-Data from robot state data" + pub_io_states.publish(msg) + + # Notes: + # - analog_input2 and analog_input3 are within ToolData + # - Where are the flags coming from? + # + # - Shall we have appropriate ur_msgs definitions in order to reflect MasterboardData, ToolData,...? + # Updates the state machine that determines whether we can program the robot. can_execute = (state.robot_mode_data.robot_mode in [RobotMode.READY, RobotMode.RUNNING]) @@ -253,6 +289,118 @@ class URConnection(object): self.__keep_running = False + + +class URConnectionRT(object): + TIMEOUT = 1.0 + + DISCONNECTED = 0 + CONNECTED = 1 + READY_TO_PROGRAM = 2 + EXECUTING = 3 + + def __init__(self, hostname, port): + self.__thread = None + self.__sock = None + self.robot_state = self.DISCONNECTED + self.hostname = hostname + self.port = port + self.last_stateRT = None + + def connect(self): + if self.__sock: + self.disconnect() + self.__buf = "" + self.robot_state = self.CONNECTED + self.__sock = socket.create_connection((self.hostname, self.port)) + self.__keep_running = True + self.__thread = threading.Thread(name="URConnectionRT", target=self.__run) + self.__thread.daemon = True + self.__thread.start() + + def disconnect(self): + if self.__thread: + self.__keep_running = False + self.__thread.join() + self.__thread = None + if self.__sock: + self.__sock.close() + self.__sock = None + self.last_state = None + self.robot_state = self.DISCONNECTED + + def __trigger_disconnected(self): + log("Robot disconnected") + self.robot_state = self.DISCONNECTED + def __trigger_ready_to_program(self): + rospy.loginfo("Robot ready to program") + def __trigger_halted(self): + log("Halted") + + def __on_packet(self, buf): + stateRT = RobotStateRT.unpack(buf) + self.last_stateRT = stateRT + + msg = RobotStateRTMsg() + msg.time = stateRT.time + msg.q_target = stateRT.q_target + msg.qd_target = stateRT.qd_target + msg.qdd_target = stateRT.qdd_target + msg.i_target = stateRT.i_target + msg.m_target = stateRT.m_target + msg.q_actual = stateRT.q_actual + msg.qd_actual = stateRT.qd_actual + msg.i_actual = stateRT.i_actual + msg.tool_acc_values = stateRT.tool_acc_values + msg.tcp_force = stateRT.tcp_force + msg.tool_vector = stateRT.tool_vector + msg.tcp_speed = stateRT.tcp_speed + msg.digital_input_bits = stateRT.digital_input_bits + msg.motor_temperatures = stateRT.motor_temperatures + msg.controller_timer = stateRT.controller_timer + msg.test_value = stateRT.test_value + msg.robot_mode = stateRT.robot_mode + msg.joint_modes = stateRT.joint_modes + pub_robot_stateRT.publish(msg) + + + msg = JointState() + msg.header.stamp = rospy.get_rostime() + msg.header.frame_id = "From real-time state data" + msg.name = joint_names + msg.position = [0.0] * 6 + for i, q in enumerate(stateRT.q_actual): + msg.position[i] = q + joint_offsets.get(joint_names[i], 0.0) + msg.velocity = stateRT.qd_actual + msg.effort = [0]*6 + pub_joint_statesRT.publish(msg) + #self.last_joint_states = msg + + def __run(self): + while self.__keep_running: + r, _, _ = select.select([self.__sock], [], [], self.TIMEOUT) + if r: + more = self.__sock.recv(4096) + if more: + self.__buf = self.__buf + more + + # Attempts to extract a packet + packet_length = struct.unpack_from("!i", self.__buf)[0] + print("PacketLength: ", packet_length, "; BufferSize: ", len(self.__buf)) + if len(self.__buf) >= packet_length: + packet, self.__buf = self.__buf[:packet_length], self.__buf[packet_length:] + self.__on_packet(packet) + else: + self.__trigger_disconnected() + self.__keep_running = False + + else: + self.__trigger_disconnected() + self.__keep_running = False + + + + def setConnectedRobot(r): global connected_robot, connected_robot_lock with connected_robot_lock: @@ -353,81 +501,39 @@ class CommanderTCPHandler(SocketServer.BaseRequestHandler): #gets all IO States and publishes them into a message elif mtype == MSG_GET_IO: - #gets digital in states - while len(buf) < 4: - buf = buf + self.recv_more() #print "MSG_GET_IO" #print type(buf) #print len(buf) #print "Buf:", [ord(b) for b in buf] - inp = struct.unpack_from("!i", buf, 0)[0] - buf = buf[4:] msg = IOStates() - for i in range(0, 10): - msg.digital_in_states.append(DigitalIn(i, (inp & (1<<i))>>i)) - #gets digital out states + #gets flag states (0-7) while len(buf) < 4: buf = buf + self.recv_more() inp = struct.unpack_from("!i", buf, 0)[0] buf = buf[4:] - for i in range(0, 10): - msg.digital_out_states.append(DigitalOut(i, (inp & (1<<i))>>i)) - ##gets flag states (0-7) - #while len(buf) < 4: - #buf = buf + self.recv_more() - #inp = struct.unpack_from("!i", buf, 0)[0] - #buf = buf[4:] - #for i in range(0, 8): - #msg.flag_states.append(Flag(i, (inp & (1<<i))>>i)) - ##gets flag states (8-15) - #while len(buf) < 4: - #buf = buf + self.recv_more() - #inp = struct.unpack_from("!i", buf, 0)[0] - #buf = buf[4:] - #for i in range(8, 16): - #msg.flag_states.append(Flag(i, (inp & (1<<i))>>i)) - ##gets flag states (16-23) - #while len(buf) < 4: - #buf = buf + self.recv_more() - #inp = struct.unpack_from("!i", buf, 0)[0] - #buf = buf[4:] - #for i in range(16, 24): - #msg.flag_states.append(Flag(i, (inp & (1<<i))>>i)) - ##gets flag states (24-31) - #while len(buf) < 4: - #buf = buf + self.recv_more() - #inp = struct.unpack_from("!i", buf, 0)[0] - #buf = buf[4:] - #for i in range(24, 32): - #msg.flag_states.append(Flag(i, (inp & (1<<i))>>i)) - #gets analog_out[0] state + for i in range(0, 8): + msg.flag_states.append(Flag(i, (inp & (1<<i))>>i)) + #gets flag states (8-15) while len(buf) < 4: buf = buf + self.recv_more() inp = struct.unpack_from("!i", buf, 0)[0] - inp /= MULT_analog buf = buf[4:] - msg.analog_out_states.append(Analog(0, inp)) - #gets analog_out[1] state + for i in range(8, 16): + msg.flag_states.append(Flag(i, (inp & (1<<i))>>i)) + #gets flag states (16-23) while len(buf) < 4: buf = buf + self.recv_more() inp = struct.unpack_from("!i", buf, 0)[0] - inp /= MULT_analog buf = buf[4:] - msg.analog_out_states.append(Analog(1, inp)) - #gets analog_in[0] state + for i in range(16, 24): + msg.flag_states.append(Flag(i, (inp & (1<<i))>>i)) + #gets flag states (24-31) while len(buf) < 4: buf = buf + self.recv_more() inp = struct.unpack_from("!i", buf, 0)[0] - inp /= MULT_analog buf = buf[4:] - msg.analog_in_states.append(Analog(0, inp)) - #gets analog_in[1] state - while len(buf) < 4: - buf = buf + self.recv_more() - inp = struct.unpack_from("!i", buf, 0)[0] - inp /= MULT_analog - buf = buf[4:] - msg.analog_in_states.append(Analog(1, inp)) + for i in range(24, 32): + msg.flag_states.append(Flag(i, (inp & (1<<i))>>i)) #gets analog_in[2] state while len(buf) < 4: buf = buf + self.recv_more() @@ -442,7 +548,7 @@ class CommanderTCPHandler(SocketServer.BaseRequestHandler): inp /= MULT_analog buf = buf[4:] msg.analog_in_states.append(Analog(3, inp)) - pub_io_states.publish(msg) + pub_io_states2.publish(msg) elif mtype == MSG_QUIT: print "Quitting" @@ -951,6 +1057,9 @@ def main(): connection.connect() connection.send_reset_program() + connectionRT = URConnectionRT(robot_hostname, RT_PORT) + connectionRT.connect() + set_io_server() service_provider = None -- GitLab