X86架构下使用示例

1 Modbus Rtu使用示例

Python
import  nrc_interface  as  nrc
import  time

class  ArmTest:
        def  demo_finger_modbus_rtu(self,  socketFd):
                """
                Modbus  RTU  控制灵巧手  Demo(Python版)
                :param  socketFd:  套接字文件描述符

                串口号是2
                """
                master_id  =  1    #  主站ID(0~8均可)

                #  =================================================
                #  1  配置  Modbus  RTU  参数
                #  =================================================
                param  =  nrc.ModbusMasterParameter()
            
                param.type  = "RTU"
                param.startAddress  = True    #  False=地址从1开始

                #  RTU  串口参数
                param.RTU.slaveId  = 2                #  从站ID
                param.RTU.port  = 2                      #  串口号
                param.RTU.baudrate  = 115200    #  波特率
                param.RTU.checkBit  = "None"    #  校验位
                param.RTU.dataBit  = 8                #  数据位
                param.RTU.stopBit  = 1                #  停止位

                #  =================================================
                #  2  写入主站参数
                #  =================================================
                ret  =  nrc.modbus_set_master_parameter(socketFd,  master_id,  param)
                if  ret  !=  nrc.SUCCESS:
                        print("设置Modbus  RTU参数失败")
                        return
                print("设置Modbus  RTU参数成功")

                #  =================================================
                #  3  打开  Modbus  主站
                #  =================================================
                ret  =  nrc.modbus_open_master(socketFd,  master_id)
                if  ret  !=  nrc.SUCCESS:
                        print("打开Modbus主站失败")
                        return
                print("打开Modbus主站成功")

                time.sleep(1)

                #  =================================================
                #  4  写多个寄存器(控制灵巧手)
                #  =================================================
                control_data  =  [20000,  0,  0,  0,  0]

                ret  =  nrc.modbus_write_multiple_holding_registers(
                        socketFd,
                        master_id,
                        1135,                #  起始地址
                        control_data  #  数据
                )
                if  ret  !=  nrc.SUCCESS:
                        print("写多个寄存器失败")
                        return
                print("写多个寄存器成功")

                time.sleep(1)

                #  =================================================
                #  5  读取寄存器验证
                #  =================================================
                read_back  =  nrc.VectorInt()

                ret  =  nrc.modbus_read_holding_registers(
                        socketFd,
                        master_id,
                        1155,    #  起始地址
                        5,          #  读取数量
                        read_back
                )
                if  ret  !=  nrc.SUCCESS:
                        print("读取寄存器失败")
                        return

                print("\n[结果]  读取数据:",  end="")
                for  v  in  read_back:
                        print(v,  end="  ")
                print()

                print("\n[完成]  灵巧手  Modbus  RTU  Demo  执行完毕!")



if  __name__  == '__main__':
        #  建立连接
      arm_test  =  ArmTest()
      socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")

      arm_test.demo_finger_modbus_rtu(socket_fd)    #调用modbus_demo

2 关节信息查询使用示例

Python
import  nrc_interface  as  nrc
import  time

class  ArmTest:
      #  查询关节信息
        def  demo_get_joint_info(self,  socketFd,  joint_id):
                joint_param  =  nrc.RobotJointParam()
                ret  =  nrc.get_robot_joint_param(socketFd,  joint_id,  joint_param)
                
                if  ret  !=  nrc.SUCCESS:
                        print(f"查询轴{joint_id}失败")
                        return
                
                print(f"===  轴{joint_id}  ===")
                print(f"减速比                    :  {joint_param.reducRatio}")
                print(f"编码器分辨率          :  {joint_param.encoderResolution}")
                print(f"软正限位                :  {joint_param.posSWLimit}")
                print(f"软负限位                :  {joint_param.negSWLimit}")
                print(f"额定转速                :  {joint_param.ratedRotSpeed}")
                print(f"最大转速                :  {joint_param.maxRotSpeed}")
                print(f"额定速度                :  {joint_param.ratedVel}")
                print(f"最大加速度            :  {joint_param.maxAcc}")
                print(f"最大减速度            :  {joint_param.maxDecel}")
                print(f"电机方向                :  {joint_param.direction}")
if  __name__  == '__main__':
        #  建立连接
      arm_test  =  ArmTest()
      socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")

3 关节实时跟踪servoJ使用示例

Python
import  nrc_interface  as  nrc
import  time

class  ArmTest:
        #关节跟踪模式
        def  demo_servoJ(self,  socket_fd):
  
          
                vmax  =  [300,  300,  .300,  300,  300,  300,  300]
                amax  =  [3000,  3000,  3000,  3000,  3000,  3000,  3000]
                jmax  =  [50000,  50000,  50000,  50000,  50000,  50000,  50000]
                nrc.open_servoJ(socket_fd,  vmax,  amax,  jmax)
                print("打开关节跟踪模式")
                print(f">  速度约束:  {vmax}  °/s")
                print(f">  加速度约束:  {amax}  °/s²")
                print(f">  加加速度约束:  {jmax}  °/s³")
                print("===  高频小增量关节跟踪启动  ===")
                time.sleep(0.2)
                
                q  =  [0,  0,  0,  0,  0,  0,  0]    #目标位置,关节一从0到100度
                while  q[0]  <  60:
                        q[0]  +=  1
                        nrc.set_servoJ_pos(socket_fd,  q)
                        time.sleep(0.01)  #发送频率,10ms/次,可以改
                
                time.sleep(5)                #确保停下来
                nrc.close_servoJ(socket_fd)
                print("===  跟踪结束  ===")
if  __name__  == '__main__':
        #  建立连接
      arm_test  =  ArmTest()
      socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")
      socket_fd_7000  =  nrc.connect_robot("192.168.1.13", "7000")



      nrc.set_servo_state(socket_fd,  1)                        #就绪状态
      time.sleep(1)
      nrc.set_current_mode(socket_fd,  2)                    #运行模式
      nrc.set_speed(socket_fd,30)                                      #30%速度
      nrc.set_servo_poweron(socket_fd)                      #上电
      arm_test.demo_servoJ(socket_fd_7000)              #开始追踪,示例是从零点坐标  #开始追踪,示例是从零点坐标(使用时请回零点),给一关节以10ms每次的频率发送0到60度  ,速度很快
      #使用此功能一定要注意安全!!!!!!!!

4 关节运动到目标点robot_movej使用示例

Python
import  nrc_interface  as  nrc
import  time

class  ArmTest:
        def  demo_arm_movej(self,  socket_fd):
                """
                七轴机械臂  MoveJ  运动  Demo
                """
                print("开始伺服上电...")
                nrc.set_servo_state(socket_fd,  1)        
                nrc.set_servo_poweron(socket_fd)      
                print("伺服已上电")
                time.sleep(1)

                moveCmd  =  nrc.MoveCmd()
                target  =  [50,  0,  0,  0,  0,  0,  0]
                moveCmd.targetPosValue.resize(7)    

                for  i  in  range(7):
                        moveCmd.targetPosValue[i]  =  target[i]        

                moveCmd.coord  =  0#关节坐标系
                moveCmd.velocity  =  20
                moveCmd.acc  =  100
                moveCmd.dec  =  100
                moveCmd.pl  =  5  

                ret  =  nrc.robot_movej(socket_fd,  moveCmd)
                print(f"调用返回值(ret)  =  {ret}")
                time.sleep(10)
                print("指令发送完成")

if  __name__  == '__main__':
        #  建立连接
      arm_test  =  ArmTest()
      socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")

      arm_test.demo_arm_movej(socket_fd)

5 直线运动到目标位置robot_movel使用示例

Python
import  nrc_interface  as  nrc
import  time

class  ArmTest:
      #  直线运动  movel
        def  demo_arm_movel(self,  socket_fd):
                print("开始伺服上电...")
                nrc.set_servo_state(socket_fd,  1)        
                nrc.set_servo_poweron(socket_fd)      
                print("伺服已上电")
                time.sleep(1)
                moveCmd  =  nrc.MoveCmd()  
                target  =  [140,  199,  243,  3.14,  0,  0,  -1]#目标位置,直角坐标系
                moveCmd.targetPosValue.resize(7)    
                for  i  in  range(7):
                        moveCmd.targetPosValue[i]  =  target[i]    

                moveCmd.coord  =  1#直角坐标系
                moveCmd.velocity  = 100
                moveCmd.acc  = 100
                moveCmd.dec  = 100
                
                ret  =  nrc.robot_movel(socket_fd,  moveCmd)
                print(f"直线运动调用返回值(ret)  =  {ret}")
                time.sleep(10)
                print("直线运动完成")
if  __name__  == '__main__':
        #  建立连接
      arm_test  =  ArmTest()
      socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")

      #  执行直线运动
      arm_test.demo_arm_movel(socket_fd)
      #使用时一定要注意安全!!!!!!!!

6 点动使用示例

Python
import  nrc_interface  as  nrc
import  time

class  ArmTest:
#  ====================  单轴点动    ====================
        def  demo_arm_start_jogging(self,  socket_fd):
                print("开始伺服上电...")
                nrc.set_servo_state(socket_fd,  1)
                nrc.set_servo_poweron(socket_fd)
                print("伺服已上电")
                time.sleep(1)

                #  点动参数
                axis  = 1              #  轴号  1~6
                dir  = True          #  方向  True=正  /  False=负

                #  调用点动
                ret  =  nrc.robot_start_jogging(socket_fd,  axis,  dir)
                print(f"单轴点动启动返回值(ret)  =  {ret}")
                print("单轴点动已开始(需手动停止)")

#  ====================  停止点动====================
        def  demo_arm_stop_jogging(self,  socket_fd):
                axis  = 1    #  要停止的轴号(必须和启动时一致)
                
                ret  =  nrc.robot_stop_jogging(socket_fd,  axis)
                print(f"停止点动返回值(ret)  =  {ret}")
                print("点动已停止")
if  __name__  == '__main__':
        #  建立连接
      arm_test  =  ArmTest()
      socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")
      #  1.  启动点动
arm_test.demo_arm_start_jogging(socket_fd)  #一轴点动一次

time.sleep(2)    #  运动2秒

#  2.  停止点动
arm_test.demo_arm_stop_jogging(socket_fd)

7 作业文件插入指令使用示例

Python
import  nrc_interface  as  nrc
import  time

class  ArmTest:
            def  job_moveJ(self,socket_fd):
                #  创建指令
                moveCmd  =  nrc.MoveCmd()
                
                #  设置参数
                moveCmd.targetPosType  = 1
#如果targetPosType=0为自定义数组,需要设置该向量值,前7位为本体值,后7位为外部轴
#如果targetPosType=1,需要设置targetPosName为"P0001"

                moveCmd.targetPosName  = "P0001"#每次插入应该使用不同name的点存储点位信息,例如插入第二个可以用"P0002"
                
                #  位置向量
                pos  =  nrc.VectorDouble(6)#6轴为例,7轴第7个pos填0
                pos[0]  = 8.0
                pos[1]  = 0.0
                pos[2]  = 0.0
                pos[3]  = 0.0
                pos[4]  = 0.0
                pos[5]  = 0.0
                
                moveCmd.targetPosValue  =  pos
                moveCmd.coord  = 0
                moveCmd.velocity  = 20
                moveCmd.velocitySync  = 20
                moveCmd.acc  = 20
                moveCmd.dec  = 20
                moveCmd.pl  = 5

                #  下发
                nrc.job_open(socket_fd, "TTT")#打开一个作业文件TTT,没有的话先创建
                time.sleep(1)
                ret  =  nrc.job_insert_moveJ(socket_fd, 1,  moveCmd)#插入指令
                print("执行结果:",  ret)      
if  __name__  == '__main__':
        #  建立连接
      arm_test  =  ArmTest()
      socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")
      arm_test.job_moveJ(socket_fd)
#这样就在作业文件TTT的第一行插入了一条moveJ,和示教器使用基本一样。重新打开示教器会自动同步作业文件,就可以看见示教器的TTT工作文件插入了一条moveJ

8 队列运动指令使用示例

Python
import  nrc_interface  as  nrc
import  time

class  ArmTest:      
  def  queue_moveJ(self,  pos_list,  socket_fd=None,  coord=0,  velocity=10,  acc=20,  dec=20,  pl=0):
                """
                队列运动模式:插入  MoveJ  并发送
                :param  socket_fd:  可选,优先使用传入的,没有则用实例默认的
                """
                fd  =  socket_fd

                pos  =  nrc.VectorDouble(len(pos_list))
                for  i,  val  in  enumerate(pos_list):
                        pos[i]  =  val

                moveCmd  =  nrc.MoveCmd()
                moveCmd.coord  =  coord
                moveCmd.targetPosType  =  nrc.PosType_data
                moveCmd.targetPosValue  =  pos
                moveCmd.velocity  =  velocity
                moveCmd.acc  =  acc
                moveCmd.dec  =  dec
                moveCmd.pl  =  pl

      
                nrc.queue_motion_push_back_moveJ(fd,  moveCmd)
                ret  =  nrc.queue_motion_get_status(fd,  True)
                
                print(f"队列  MoveJ  返回值(ret)  =  {ret}")
                return  ret
        #  ======================  队列控制:MoveC  ======================
        def  queue_moveC(self,  pos_list,  socket_fd=None,  coord=0,  velocity=10,  acc=100,  dec=100,  pl=5):
                """
                队列运动模式:插入  MoveC  并发送
                :param  socket_fd:  可选,优先使用传入的,没有则用实例默认的
                """
                fd  =  socket_fd

                pos  =  nrc.VectorDouble(len(pos_list))
                for  i,  val  in  enumerate(pos_list):
                        pos[i]  =  val

                moveCmd  =  nrc.MoveCmd()
                moveCmd.coord  =  coord
                moveCmd.targetPosType  =  nrc.PosType_data
                moveCmd.targetPosValue  =  pos
                moveCmd.velocity  =  velocity
                moveCmd.acc  =  acc
                moveCmd.dec  =  dec
                moveCmd.pl  =  pl

      
                nrc.queue_motion_push_back_moveC(fd,  moveCmd)
                ret  =  nrc.queue_motion_get_status(fd,  True)
                
                print(f"队列  MoveC  返回值(ret)  =  {ret}")
                return  ret
        def  queue_moveS(self,  pos_list,  socket_fd=None,  coord=0,  velocity=10,  acc=20,  dec=20,  pl=0):
                """
                队列运动模式:插入  MoveS  并发送
                :param  socket_fd:  可选,优先使用传入的,没有则用实例默认的
                """
                fd  =  socket_fd

                pos  =  nrc.VectorDouble(len(pos_list))
                for  i,  val  in  enumerate(pos_list):
                        pos[i]  =  val

                moveCmd  =  nrc.MoveCmd()
                moveCmd.coord  =  coord
                moveCmd.targetPosType  =  nrc.PosType_data
                moveCmd.targetPosValue  =  pos
                moveCmd.velocity  =  velocity
                moveCmd.acc  =  acc
                moveCmd.dec  =  dec
                moveCmd.pl  =  pl

      
                nrc.queue_motion_push_back_moveC(fd,  moveCmd)
                ret  =  nrc.queue_motion_get_status(fd,  True)
                
                print(f"队列  MoveS  返回值(ret)  =  {ret}")
                return  ret
if  __name__  == '__main__':
        #  建立连接
      arm_test  =  ArmTest()
      socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")
      nrc.queue_motion_set_status(socket_fd,  True)#打开队列模式
      time,sleep(2)
      nrc.set_speed(socket_fd,40)#运行速度
      arm_test.queue_moveJ(socket_fd=socket_fd,pos_list=[50.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0])#本示例从零点开始运动,到j1=50度,回零点
      arm_test.queue_moveJ(socket_fd=socket_fd,pos_list=[0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0])
      nrc.queue_motion_send_to_controller(socket_fd,2)#发送二个目标位置
      time.sleep(20)
      nrc.queue_motion_set_status(socket_fd,  False)#关闭队列模式

9 欧拉角,四元素,位姿矩阵,旋转矩阵相互转化使用示例

Python
import  nrc_interface  as  nrc
import  time
class  ArmTest:
        #  ======================    四元数  转  欧拉角  ======================
        def  get_quat2rpy(self,  qx,  qy,  qz,  qw,  socket_fd=None):
          
                #  1.  创建输入四元数  vector(长度4)
                fd  =  socket_fd
                quat_vec  =  nrc.VectorDouble(4)
                quat_vec[0]  =  qx
                quat_vec[1]  =  qy
                quat_vec[2]  =  qz
                quat_vec[3]  =  qw

                #  2.  创建输出欧拉角  vector(长度3)
                rpy_vec  =  nrc.VectorDouble(3)

                #  3.  调用接口
                ret  =  nrc.get_quat2rpy(fd,  quat_vec,  rpy_vec)

                #  4.  读取结果
                rx  =  rpy_vec[0]
                ry  =  rpy_vec[1]
                rz  =  rpy_vec[2]

                print(f"转换返回值  ret  =  {ret}")
                print(f"欧拉角  Rx={rx:.3f},  Ry={ry:.3f},  Rz={rz:.3f}")
                
                return  ret,  rx,  ry,  rz
        #  ======================  欧拉角  转  四元数  ======================
        def  get_rpy2quat(self,  rx,  ry,  rz,  socket_fd=None):
                fd  =  socket_fd

                #  输入:欧拉角  RPY  长度  3
                rpy_vec  =  nrc.VectorDouble(3)
                rpy_vec[0]  =  rx
                rpy_vec[1]  =  ry
                rpy_vec[2]  =  rz

                #  输出:四元数  长度  4
                quat_vec  =  nrc.VectorDouble(4)

                #  调用接口
                ret  =  nrc.get_rpy2quat(fd,  rpy_vec,  quat_vec)

                #  取出四元数结果
                qx  =  quat_vec[0]
                qy  =  quat_vec[1]
                qz  =  quat_vec[2]
                qw  =  quat_vec[3]

                print(f"rpy2quat  返回值:  {ret}")
                print(f"四元数结果:  qx={qx:.3f},  qy={qy:.3f},  qz={qz:.3f},  qw={qw:.3f}")

                return  ret,  qx,  qy,  qz,  qw
        #    欧拉角  转  旋转矩阵
        def  get_rpy2r(self,  rx,  ry,  rz,  socket_fd=None):
                fd  =  socket_fd

                #  输入:欧拉角  RPY  长度  3
                rpy_vec  =  nrc.VectorDouble(3)
                rpy_vec[0]  =  rx
                rpy_vec[1]  =  ry
                rpy_vec[2]  =  rz

                #  输出:旋转矩阵  长度  9(行主序)
                r_vec  =  nrc.VectorDouble(9)

                #  调用官方接口
                ret  =  nrc.get_rpy2r(fd,  rpy_vec,  r_vec)

                #  取出旋转矩阵  9  个值
                r00  =  r_vec[0]
                r01  =  r_vec[1]
                r02  =  r_vec[2]
                r10  =  r_vec[3]
                r11  =  r_vec[4]
                r12  =  r_vec[5]
                r20  =  r_vec[6]
                r21  =  r_vec[7]
                r22  =  r_vec[8]

                #  打印
                print(f"rpy2r  返回值:  {ret}")
                print(f"旋转矩阵结果:  r00={r00:.3f},  r01={r01:.3f},  r02={r02:.3f}")
                print(f"                            r10={r10:.3f},  r11={r11:.3f},  r12={r12:.3f}")
                print(f"                            r20={r20:.3f},  r21={r21:.3f},  r22={r22:.3f}")

                #  返回:ret  +  9个矩阵值
                return  ret,  r00,  r01,  r02,  r10,  r11,  r12,  r20,  r21,  r22
        #位姿  转  旋转矩阵
        def  get_rt2r(self,  tr_matrix,  socket_fd=None):
                fd  =  socket_fd

                #  输入:位姿矩阵  长度  16(行主序)
                tr_vec  =  nrc.VectorDouble(16)
                for  i  in  range(16):
                        tr_vec[i]  =  tr_matrix[i]

                #  输出:旋转矩阵  长度  9(行主序)
                r_vec  =  nrc.VectorDouble(9)

                #  调用接口
                ret  =  nrc.get_tr2r(fd,  tr_vec,  r_vec)

                #  取出旋转矩阵  9  个值
                r00  =  r_vec[0]
                r01  =  r_vec[1]
                r02  =  r_vec[2]
                r10  =  r_vec[3]
                r11  =  r_vec[4]
                r12  =  r_vec[5]
                r20  =  r_vec[6]
                r21  =  r_vec[7]
                r22  =  r_vec[8]

                #  打印
                print(f"rt2r  返回值:  {ret}")
                print(f"旋转矩阵结果:  r00={r00:.3f},  r01={r01:.3f},  r02={r02:.3f}")
                print(f"                            r10={r10:.3f},  r11={r11:.3f},  r12={r12:.3f}")
                print(f"                            r20={r20:.3f},  r21={r21:.3f},  r22={r22:.3f}")

                #  返回格式ret  +  9个矩阵值
                return  ret,  r00,  r01,  r02,  r10,  r11,  r12,  r20,  r21,  r22
        #  旋转矩阵  转  位姿矩阵
        def  get_r2tr(self,  r00,  r01,  r02,  r10,  r11,  r12,  r20,  r21,  r22,  socket_fd=None):
                fd  =  socket_fd

                #  输入:旋转矩阵  长度9(行主序)
                r_vec  =  nrc.VectorDouble(9)
                r_vec[0]  =  r00
                r_vec[1]  =  r01
                r_vec[2]  =  r02
                r_vec[3]  =  r10
                r_vec[4]  =  r11
                r_vec[5]  =  r12
                r_vec[6]  =  r20
                r_vec[7]  =  r21
                r_vec[8]  =  r22

                #  输出:位姿矩阵  长度16(行主序)
                tr_res  =  nrc.VectorDouble(16)

                #  调用接口
                ret  =  nrc.get_r2tr(fd,  r_vec,  tr_res)

                #  取出位姿矩阵16个值
                tr00  =  tr_res[0]
                tr01  =  tr_res[1]
                tr02  =  tr_res[2]
                tr03  =  tr_res[3]
                tr10  =  tr_res[4]
                tr11  =  tr_res[5]
                tr12  =  tr_res[6]
                tr13  =  tr_res[7]
                tr20  =  tr_res[8]
                tr21  =  tr_res[9]
                tr22  =  tr_res[10]
                tr23  =  tr_res[11]
                tr30  =  tr_res[12]
                tr31  =  tr_res[13]
                tr32  =  tr_res[14]
                tr33  =  tr_res[15]

                #  打印
                print(f"r2tr  返回值:  {ret}")
                print(f"位姿矩阵结果:  tr00={tr00:.3f},  tr01={tr01:.3f},  tr02={tr02:.3f},  tr03={tr03:.3f}")
                print(f"                            tr10={tr10:.3f},  tr11={tr11:.3f},  tr12={tr12:.3f},  tr13={tr13:.3f}")
                print(f"                            tr20={tr20:.3f},  tr21={tr21:.3f},  tr22={tr22:.3f},  tr23={tr23:.3f}")
                print(f"                            tr30={tr30:.3f},  tr31={tr31:.3f},  tr32={tr32:.3f},  tr33={tr33:.3f}")

                #  返回:ret  +  16个位姿值
                return  ret,  tr00,  tr01,  tr02,  tr03,  tr10,  tr11,  tr12,  tr13,  tr20,  tr21,  tr22,  tr23,  tr30,  tr31,  tr32,  tr33
if  __name__  == '__main__':
        #  建立连接
        arm_test  =  ArmTest()
        socket_fd  =  nrc.connect_robot("192.168.1.13", "6001")
        arm_test.get_rpy2quat(-2.9,0.167,-0.777,socket_fd)
        arm_test.get_quat2rpy(-0.080,  0.919,  0.365,  0.122,socket_fd)
        arm_test.get_rpy2r(-2.9,0.167,-0.777,socket_fd)
        arm_test.get_r2tr(0.703,  0.691,  0.166,  0.652,  -0.720,  0.236,  0.283,  -0.057,  -0.957,  socket_fd)
        tr  =  [
        0.703,  0.691,  0.166,  0.000,
        0.652,  -0.720,  0.236,  0.000,
        0.283,  -0.057,  -0.957,  0.000,
        0.000,  0.000,  0.000,  1.000
        ]
arm_test.get_rt2r(tr,  socket_fd  )