当前位置: 首页 > article >正文

新松机械臂 2001端口服务的客户端例程

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。

源码指引:github源码指引_初级代码游戏的博客-CSDN博客

C#是我多年以来的业余爱好,新搞的东西能用C#的就用C#了。


        新松机械臂报告状态的端口是2001,每100毫秒报告一次状态,每次报告数据长度1468字节。

        这个端口只用来报告状态,控制则使用2000端口。

        获取状态非常简单,连接上去,读取数据,按照格式拆分数据即可。具体数据数据格式见开发手册。

目录

一、C++头文件

二、main函数

三、核心代码

四、运行


 

一、C++头文件

         只需要使用C++头文件DucoRobat.h即可。其实并不需要这个头文件,本例程中引入是因为借用了里面定义好的状态结构而已:

// 机器人相关信息
struct RobotStatusList
{std::vector<double>  jointExpectPosition;   // 目标关节位置std::vector<double>  jointExpectVelocity;   // 目标角速度std::vector<double>  jointExpectAccelera;   // 目标角加速度std::vector<double>  jointActualPosition;   // 实际关节位置std::vector<double>  jointActualVelocity;   // 实际角速度std::vector<double>  jointActualAccelera;   // 实际角加速度std::vector<double>  jointActualCurrent;    // 实际关节电流std::vector<double>  jointTemperature;      // 时间关节温度std::vector<double>  driverTemperature;     // 未使用std::vector<double>  cartExpectPosition;    // 目标末端位姿std::vector<double>  cartExpectVelocity;    // 目标末端速度std::vector<double>  cartExpectAccelera;    // 目标末端加速度std::vector<double>  cartActualPosition;    // 实际末端位姿std::vector<double>  cartActualVelocity;    // 实际末端速度std::vector<double>  cartActualAccelera;    // 实际末端加速度std::vector<bool>    slaveReady;            // 从站状态bool    collision;       // 是否发生碰撞int8_t  collisionAxis;   // 发生碰撞的关节bool    emcStopSignal;   // 未使用int8_t  robotState;      // 机器人状态int32_t robotError;      // 机器人错误码
};

二、main函数

int main(int argc, char** argv)
{if (!InitActiveApp("DOUCO", 1024 * 1024 * 10, argc, argv))return 1;thelog << "新松机器人 TCP及IP接口" << endi;WORD sockVersion = MAKEWORD(1, 1);WSADATA wsaData;if (WSAStartup(sockVersion, &wsaData) != 0){return 0;}bool bExitCmd = false;thread t(CMyDUCO::VirtualServer, &bExitCmd);//模拟服务SleepSeconds(1);CMyDUCO myduco;string ip = "127.0.0.1";//正式使用修改为设备实际IPthelog << "连接 " << ip << " ......"<< endi;if (!myduco.Recv(ip.c_str())){thelog << "连接到 " << ip << " 失败" << ende;}else{myduco.ProcessFrame();myduco.Print();myduco.Save();}while (true)SleepSeconds(5);bExitCmd = true;t.join();WSACleanup();return 0;
}

        这个代码默认访问自带的模拟服务,实际使用修改目标IP(代码中已标注)。

三、核心代码

// DUCO.h : 新松机器人 TCP及IP接口
//#include <iostream>
//#include "DucoCobot.h"
//using namespace DucoRPC;
using namespace std;
#include "env/myUtil.h"
#include "function/htmldoc.h"
#include "function/mysocket.h"
using namespace ns_my_std;#pragma comment(lib,"ws2_32.lib")
// 机器人相关信息
struct RobotStatusList
{std::vector<double>  jointExpectPosition;   // 目标关节位置std::vector<double>  jointExpectVelocity;   // 目标角速度std::vector<double>  jointExpectAccelera;   // 目标角加速度std::vector<double>  jointActualPosition;   // 实际关节位置std::vector<double>  jointActualVelocity;   // 实际角速度std::vector<double>  jointActualAccelera;   // 实际角加速度std::vector<double>  jointActualCurrent;    // 实际关节电流std::vector<double>  jointTemperature;      // 时间关节温度std::vector<double>  driverTemperature;     // 未使用std::vector<double>  cartExpectPosition;    // 目标末端位姿std::vector<double>  cartExpectVelocity;    // 目标末端速度std::vector<double>  cartExpectAccelera;    // 目标末端加速度std::vector<double>  cartActualPosition;    // 实际末端位姿std::vector<double>  cartActualVelocity;    // 实际末端速度std::vector<double>  cartActualAccelera;    // 实际末端加速度std::vector<bool>    slaveReady;            // 从站状态bool    collision;       // 是否发生碰撞int8_t  collisionAxis;   // 发生碰撞的关节bool    emcStopSignal;   // 未使用int8_t  robotState;      // 机器人状态int32_t robotError;      // 机器人错误码
};constexpr int frame_size = 1468;
class CMyDUCO
{
private:int32_t _getUInt(int byte_pos){if (4 != sizeof(int32_t))throw "4 != sizeof(int32_t)";int32_t tmp;memcpy(&tmp, frame + byte_pos, sizeof(int32_t));return tmp;}float _getFloat(int byte_pos){if (4 != sizeof(float))throw "4 != sizeof(float)";float tmp;memcpy(&tmp, frame + byte_pos, sizeof(float));return tmp;}void _FloatX(vector<double>& vd7, int count, int byte_pos){vd7.clear();for (int i = 0; i < count; ++i){vd7.push_back(_getFloat(byte_pos + i * 4));}}union{char frame[frame_size];float _;}m_frame;char* frame = m_frame.frame;RobotStatusList m_RobotStatusList;
public:bool Save(){CEasyFile file;for (int i = 0; i < 100; ++i){char buf[256];sprintf(buf, "data%03d.dat", i);if (file.IsFileExist(buf))continue;return file.WriteFile(buf, frame, frame_size);}thelog << "已经存在的文件太多" << ende;return false;}void ProcessFrame(){// 目标关节位置_FloatX(m_RobotStatusList.jointExpectPosition, 7, 112);// 目标角速度_FloatX(m_RobotStatusList.jointExpectVelocity, 7, 140);// 目标角加速度_FloatX(m_RobotStatusList.jointExpectAccelera, 7, 168);// 实际关节位置_FloatX(m_RobotStatusList.jointActualPosition, 7, 0);// 实际角速度_FloatX(m_RobotStatusList.jointActualVelocity, 7, 28);// 实际角加速度_FloatX(m_RobotStatusList.jointActualAccelera, 7, 56);// 实际关节电流_FloatX(m_RobotStatusList.jointActualCurrent, 7, 252);// 实际关节温度_FloatX(m_RobotStatusList.jointTemperature, 7, 224);// 目标末端位姿_FloatX(m_RobotStatusList.cartExpectPosition, 6, 464);// 目标末端速度_FloatX(m_RobotStatusList.cartExpectVelocity, 6, 488);// 目标末端加速度_FloatX(m_RobotStatusList.cartExpectAccelera, 6, 512);// 实际末端位姿_FloatX(m_RobotStatusList.cartActualPosition, 6, 368);// 实际末端速度_FloatX(m_RobotStatusList.cartActualVelocity, 6, 392);// 实际末端加速度_FloatX(m_RobotStatusList.cartActualAccelera, 6, 416);// 是否发生碰撞m_RobotStatusList.collision = (1 == frame[1452]);// 发生碰撞的关节m_RobotStatusList.collisionAxis = frame[1453];// 机器人状态m_RobotStatusList.robotState = frame[1449];// 机器人错误码m_RobotStatusList.robotError = _getUInt(1456);}void Random(){static int base = 0;float* p = &m_frame._;for (int i = 0; i < frame_size / 4; ++i){p[i] = base+i;}++base;// 是否发生碰撞frame[1452] = 1;// 发生碰撞的关节frame[1453] = 6;// 机器人状态frame[1449] = 9;// 机器人错误码*(int32_t*)&frame[1456] = 10;}void _PrintV(CHtmlDoc::CHtmlTable2 &table,vector<double> & vectorD, char const* title){table.AddLine();table.AddData(title);for (auto v : vectorD){table.AddData(v, 2);}}void Print(){CHtmlDoc::CHtmlTable2 table;table.AddCol("名称");for (int i = 0; i < 7; ++i){char buf[32];sprintf(buf, "关节%d", i + 1);table.AddCol(buf, CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);}_PrintV(table, m_RobotStatusList.jointExpectPosition, "目标关节位置");_PrintV(table, m_RobotStatusList.jointExpectVelocity, "目标角速度");_PrintV(table, m_RobotStatusList.jointExpectAccelera, "目标角加速度");_PrintV(table, m_RobotStatusList.jointActualPosition, "实际关节位置");_PrintV(table, m_RobotStatusList.jointActualVelocity, "实际角速度");_PrintV(table, m_RobotStatusList.jointActualAccelera, "实际角加速度");_PrintV(table, m_RobotStatusList.jointActualCurrent, "实际关节电流");_PrintV(table, m_RobotStatusList.jointTemperature, "时间关节温度");_PrintV(table, m_RobotStatusList.driverTemperature, "未使用");_PrintV(table, m_RobotStatusList.cartExpectPosition, "目标末端位姿");_PrintV(table, m_RobotStatusList.cartExpectVelocity, "目标末端速度");_PrintV(table, m_RobotStatusList.cartExpectAccelera, "目标末端加速度");_PrintV(table, m_RobotStatusList.cartActualPosition, "实际末端位姿");_PrintV(table, m_RobotStatusList.cartActualVelocity, "实际末端速度");_PrintV(table, m_RobotStatusList.cartActualAccelera, "实际末端加速度");theLog << table.MakeTextTable() << endi;theLog << endl << m_RobotStatusList.collision << " 是否发生碰撞" << endl;theLog << (int)m_RobotStatusList.collisionAxis << " 发生碰撞的关节" << endl;theLog << (int)m_RobotStatusList.robotState << " 机器人状态" << endl;theLog << m_RobotStatusList.robotError << " 机器人错误码" << endi;}//接收数据bool Recv(char const * ip){CMySocket s;if (!s.Connect(ip, 2001)){thelog << "连接失败 "<<ip << ende;return false;}thelog << "连接成功 " << ip << endi;int count = 0;while (count != frame_size){long readCount = 0;if (!s.Recv(frame + count, frame_size - count, &readCount)){thelog << "接收失败 " << ip << ende;s.Close();return false;}thelog << readCount<<" 收到数据 " << count << endi;count += readCount;}thelog << "收到数据 " << count << endi;s.Close();return count == frame_size;}//虚拟服务static void VirtualServer(bool * pExitCmd){thelog.SetSource("TEST SERVER");CMySocket s;if (!s.Listen(2001)){thelog << "监听端口2001失败" << ende;exit(1);}thelog << "服务已创建" << endi;while (!*pExitCmd){bool tmp_bool;if (!s.IsSocketReadReady(1, tmp_bool)){thelog << "IsSocketReadReady失败" << ende;exit(1);}if (!tmp_bool)continue;CMySocket client_socket = s.Accept();if (!client_socket.IsConnected()){thelog << "Accept失败" << ende;exit(1);}thelog << "Accept成功" << endi;CMyDUCO myDUCO;myDUCO.Random();client_socket.Send(myDUCO.frame, frame_size);client_socket.Close();}s.Close();thelog << "服务结束" << endi;}
};

        这个代码已经把所需的结构直接放进来了,不需要包含DucoRobat.h。

        代码主要功能:

  • Save 保存到当前目录
  • ProcessFrame 解析收到的数据
  • Random 用于模拟服务生成数据,其实并不是随机,而是递增
  • Print 输出表格
  • Recv 接收数据
  • VirtualServer 内置模拟服务

四、运行

        运行起来结果如下:

[05-30 11:13:55][应用][信息][C:\working\IoT\DUCO\main_t.cpp:  12(main)][  0.00]新松机器人 TCP及IP接口
[05-30 11:13:55][TEST SERVER][12824- 1][信息][C:\working\IoT\DUCO\myDUCO.h: 230(VirtualServer)][  0.02]服务已创建
[05-30 11:13:56][应用][12824][信息][C:\working\IoT\DUCO\main_t.cpp:  27(main)][  1.01]连接 127.0.0.1 ......
[05-30 11:13:56][应用][12824][信息][C:\working\IoT\DUCO\myDUCO.h: 199(Recv)][  1.01]连接成功 127.0.0.1
[05-30 11:13:56][TEST SERVER][12824- 1][信息][C:\working\IoT\DUCO\myDUCO.h: 247(VirtualServer)][  1.01]Accept成功
[05-30 11:13:56][应用][12824][信息][C:\working\IoT\DUCO\myDUCO.h: 211(Recv)][  1.01]1468 收到数据 0
[05-30 11:13:56][应用][12824][信息][C:\working\IoT\DUCO\myDUCO.h: 215(Recv)][  1.01]收到数据 1468
[05-30 11:13:56][应用][12824][信息]
名称            关节1  关节2  关节3  关节4  关节5  关节6 关节7
-------------- ------ ------ ------ ------ ------ ------ -----
目标关节位置    28.00  29.00  30.00  31.00  32.00  33.00 34.00
目标角速度      35.00  36.00  37.00  38.00  39.00  40.00 41.00
目标角加速度    42.00  43.00  44.00  45.00  46.00  47.00 48.00
实际关节位置     0.00   1.00   2.00   3.00   4.00   5.00  6.00
实际角速度       7.00   8.00   9.00  10.00  11.00  12.00 13.00
实际角加速度    14.00  15.00  16.00  17.00  18.00  19.00 20.00
实际关节电流    63.00  64.00  65.00  66.00  67.00  68.00 69.00
时间关节温度    56.00  57.00  58.00  59.00  60.00  61.00 62.00
未使用
目标末端位姿   116.00 117.00 118.00 119.00 120.00 121.00
目标末端速度   122.00 123.00 124.00 125.00 126.00 127.00
目标末端加速度 128.00 129.00 130.00 131.00 132.00 133.00
实际末端位姿    92.00  93.00  94.00  95.00  96.00  97.00
实际末端速度    98.00  99.00 100.00 101.00 102.00 103.00
实际末端加速度 104.00 105.00 106.00 107.00 108.00 109.00
-------------- ------ ------ ------ ------ ------ ------ -----[05-30 11:13:56][应用][12824][信息]
1 是否发生碰撞
6 发生碰撞的关节
9 机器人状态
10 机器人错误码

        其实相当简单。


(这里是文档结束)

http://www.lryc.cn/news/2400695.html

相关文章:

  • 电脑网络重置,找不到原先自家的WIFI,手机还能正常连接并上网
  • 期末复习(学习)之机器学习入门基础
  • 网络各类型(BMA,NBMA,P2P)
  • Linux 库文件的查看和管理
  • Java设计模式深度解析:策略模式的核心原理与实战应用
  • 【计算机网络】第3章:传输层—概述、多路复用与解复用、UDP
  • 6、在树莓派上安装 NTP(Network Time Protocol )服务的步骤
  • 神经符号AI的企业应用:结合符号推理与深度学习的混合智能
  • VSCode 中 C/C++ 安装、配置、使用全攻略:小白入门指南
  • 重温经典算法——希尔排序
  • CortexON:开源的多代理AI系统无缝自动化和简化日常任务
  • 海信IP810N-海思MV320芯片-安卓9-2+16G-免拆优盘卡刷固件包
  • 【Golang】使用gin框架导出excel和csv文件
  • 【unity游戏开发入门到精通——通用篇】AssetBundle(AB包)和AssetBundleBrowser的使用介绍
  • 2025年6月4日收获
  • leetcode hot100 链表(二)
  • 6. MySQL基本查询
  • JavaWeb简介
  • CMS32M65xx/67xx系列CoreMark跑分测试
  • 中国区域30m/15天植被覆盖度数据集(2010-2022)
  • LabVIEW准分子激光器智能控制系统
  • 微服务面试资料1
  • Pytest Fixture 详解
  • 力扣HOT100之二分查找:74. 搜索二维矩阵
  • 【前端】前后端通信
  • 编程技能:格式化打印04,sprintf
  • C语言基础(11)【函数1】
  • R语言基础| 下载、安装
  • 【hive sql】窗口函数
  • Ubuntu24.04 交叉编译 aarch64 ffmpeg