浏览代码

Merge remote-tracking branch 'origin/yct' into zzw

# Conflicts:
#	.gitignore
#	CMakeLists.txt
#	error.h
#	main.cpp
zx 5 年之前
父节点
当前提交
4e62f12958
共有 14 个文件被更改,包括 699 次插入2 次删除
  1. 7 0
      .gitignore
  2. 18 0
      .vscode/c_cpp_properties.json
  3. 56 0
      .vscode/settings.json
  4. 3 1
      CMakeLists.txt
  5. 11 1
      error.h
  6. 2 0
      main.cpp
  7. 115 0
      plc/LibmodbusWrapper.cpp
  8. 36 0
      plc/LibmodbusWrapper.h
  9. 35 0
      plc/StdCondition.cpp
  10. 25 0
      plc/StdCondition.h
  11. 240 0
      plc/plc_communicator.cpp
  12. 93 0
      plc/plc_communicator.h
  13. 26 0
      plc/plc_task.cpp
  14. 32 0
      plc/plc_task.h

+ 7 - 0
.gitignore

@@ -29,6 +29,7 @@ obj/
 [Rr]elease*/
 _ReSharper*/
 [Tt]est[Rr]esult*
+<<<<<<< HEAD
 *.make 
 *.o
 *.bin
@@ -37,3 +38,9 @@ _ReSharper*/
 *.internal
 *.cbp
 *.check_cache
+=======
+.vs/
+#Nuget packages folder
+packages/
+build/
+>>>>>>> origin/yct

+ 18 - 0
.vscode/c_cpp_properties.json

@@ -0,0 +1,18 @@
+{
+    "configurations": [
+        {
+            "name": "Linux",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "/usr/local/include/modbus",
+                "${workspaceFolder}/task"
+            ],
+            "defines": [],
+            "compilerPath": "/usr/bin/clang",
+            "cStandard": "c11",
+            "cppStandard": "c++17",
+            "intelliSenseMode": "clang-x64"
+        }
+    ],
+    "version": 4
+}

+ 56 - 0
.vscode/settings.json

@@ -0,0 +1,56 @@
+{
+    "files.associations": {
+        "thread": "cpp",
+        "cctype": "cpp",
+        "clocale": "cpp",
+        "cmath": "cpp",
+        "cstdarg": "cpp",
+        "cstddef": "cpp",
+        "cstdio": "cpp",
+        "cstdlib": "cpp",
+        "cstring": "cpp",
+        "ctime": "cpp",
+        "cwchar": "cpp",
+        "cwctype": "cpp",
+        "array": "cpp",
+        "atomic": "cpp",
+        "strstream": "cpp",
+        "*.tcc": "cpp",
+        "bitset": "cpp",
+        "chrono": "cpp",
+        "cinttypes": "cpp",
+        "complex": "cpp",
+        "condition_variable": "cpp",
+        "cstdint": "cpp",
+        "deque": "cpp",
+        "list": "cpp",
+        "unordered_map": "cpp",
+        "vector": "cpp",
+        "exception": "cpp",
+        "algorithm": "cpp",
+        "functional": "cpp",
+        "ratio": "cpp",
+        "system_error": "cpp",
+        "tuple": "cpp",
+        "type_traits": "cpp",
+        "fstream": "cpp",
+        "initializer_list": "cpp",
+        "iomanip": "cpp",
+        "iosfwd": "cpp",
+        "iostream": "cpp",
+        "istream": "cpp",
+        "limits": "cpp",
+        "memory": "cpp",
+        "mutex": "cpp",
+        "new": "cpp",
+        "ostream": "cpp",
+        "numeric": "cpp",
+        "sstream": "cpp",
+        "stdexcept": "cpp",
+        "streambuf": "cpp",
+        "cfenv": "cpp",
+        "utility": "cpp",
+        "typeindex": "cpp",
+        "typeinfo": "cpp"
+    }
+}

+ 3 - 1
CMakeLists.txt

@@ -13,9 +13,11 @@ FIND_PACKAGE(Glog REQUIRED)
 set(CMAKE_MODULE_PATH "/usr/local/share/")
 
 set(CMAKE_CXX_FLAGS "-std=c++11 -msse -msse2 -msse3 -msse4 -msse4.1 -msse4.2")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-as-needed")
 set(CMAKE_BUILD_TYPE "RELEASE")
 
+
+#find_package(Eigen3 REQUIRED)
+
 include_directories(
         laser
         plc

+ 11 - 1
error.h

@@ -7,7 +7,17 @@ enum ERROR_CODE
 
     LASER_INIT_FAILED	=	0x010102FF,
 
-    PLC_INIT_ERROR=0x02010000,
+
+
+PLC_INIT_ERROR=0x02010000,
+PLC_UNKNOWN_ERROR,
+PLC_SET_CALLBACK_ERROR,
+PLC_IP_PORT_ERROR,
+PLC_SLAVE_ID_ERROR,
+PLC_CONNECTION_FAILED,
+PLC_READ_FAILED,
+PLC_WRITE_FAILED,
+PLC_NOT_ENOUGH_DATA_ERROR,
 
     //Locater.cpp error from 0x0301000-0x030100FF
     LOCATER_TASK_INIT_CLOUD_EMPTY=0x03010000,

+ 2 - 0
main.cpp

@@ -2,10 +2,12 @@
 // Created by zx on 2019/12/28.
 //
 #include <iostream>
+#include "plc/plc_communicator.h"
 
 
 int main(int argc,char* argv[])
 {
+
     getchar();
     return 0;
 }

+ 115 - 0
plc/LibmodbusWrapper.cpp

@@ -0,0 +1,115 @@
+
+#include "LibmodbusWrapper.h"
+
+namespace modbus
+{
+    CLibmodbusWrapper::CLibmodbusWrapper()
+        :_ctx(NULL)
+        , _ip("")
+        ,_port(-1)
+        ,_slave_id(-1)
+    {
+    }
+
+
+    CLibmodbusWrapper::~CLibmodbusWrapper()
+    {
+        deinitialize();
+    }
+
+    void CLibmodbusWrapper::deinitialize()
+    {
+        if (_ctx)
+        {
+            modbus_close(_ctx);
+            modbus_free(_ctx);
+            _ctx = NULL;
+            _ip = "";
+            _port = -1;
+            _slave_id = -1;
+        }
+    }
+    int CLibmodbusWrapper::initialize(const char *ip, int port, int slave_id)
+    {
+        int rc = 0;
+
+        this->deinitialize();
+
+        _ctx = modbus_new_tcp(ip, port);
+        if (_ctx == NULL)
+        {
+            //����ʧ��
+            fprintf(stderr, "CLibmodbusWrapper: Unable to allocate libmodbus context\n");
+            return -3;
+        }
+
+        // ���õ���ģʽ
+        modbus_set_debug(_ctx, FALSE);
+
+        // �������ӵ�slave�ţ��˴�Ϊ1
+        rc = modbus_set_slave(_ctx, slave_id);
+        if (rc == -1)
+        {
+            fprintf(stderr, "CLibmodbusWrapper: Invalid slave ID\n");
+            modbus_free(_ctx);
+            _ctx = NULL;
+            return -2;
+        }
+
+        rc = modbus_connect(_ctx);
+        if (rc == -1)
+        {
+            fprintf(stderr, "CLibmodbusWrapper: Connection failed: %s\n", modbus_strerror(errno));
+            modbus_free(_ctx);
+            _ctx = NULL;
+            return -1;
+        }
+
+        _ip = ip;
+        _port = port;
+        _slave_id = slave_id;
+
+        return 0;
+    }
+
+    int CLibmodbusWrapper::read_registers(int addr, int nb, uint16_t *dest)
+    {
+        if (modbus_read_registers(_ctx, addr, nb, dest) == -1)
+        {
+            fprintf(stderr, "CLibmodbusWrapper: Read registers failed: %s\n", modbus_strerror(errno));
+            return -1;
+        }
+        return 0;
+    }
+
+    int CLibmodbusWrapper::write_registers(int addr, int nb, uint16_t *dest)
+    {
+        if (modbus_write_registers(_ctx, addr, nb, dest) == -1)
+        {
+            fprintf(stderr, "CLibmodbusWrapper: Write registers failed: %s\n", modbus_strerror(errno));
+            return -1;
+        }
+        return 0;
+    }
+
+
+    int CLibmodbusWrapper::read_register(int addr, uint16_t *dest)
+    {
+        if (modbus_read_registers(_ctx, addr, 1, dest) == -1)
+        {
+            fprintf(stderr, "CLibmodbusWrapper: Read registers failed: %s\n", modbus_strerror(errno));
+            return -1;
+        }
+        return 0;
+    }
+
+    int CLibmodbusWrapper::write_register(int addr, uint16_t *dest)
+    {
+        if (modbus_write_registers(_ctx, addr, 1, dest) == -1)
+        {
+            fprintf(stderr, "CLibmodbusWrapper: Write registers failed: %s\n", modbus_strerror(errno));
+            return -1;
+        }
+        return 0;
+    }
+}

+ 36 - 0
plc/LibmodbusWrapper.h

@@ -0,0 +1,36 @@
+#pragma once
+#include <stdio.h>
+#include <errno.h>
+#include <string>
+#include "modbus.h"
+
+namespace modbus
+{
+    class CLibmodbusWrapper
+    {
+    public:
+        CLibmodbusWrapper();
+        virtual ~CLibmodbusWrapper();
+        int initialize(const char *ip, int port, int slave_id);
+        void deinitialize();
+
+    public:
+        int read_registers(int addr, int nb, uint16_t *dest);
+        int write_registers(int addr, int nb, uint16_t *dest);
+
+        int read_register(int addr, uint16_t *dest);
+        int write_register(int addr, uint16_t *dest);
+
+        inline bool is_connected() { return (0 == _ctx) ? false : true; };
+        inline std::string getIP() { return _ip; };
+        inline int getPort() { return _port; };
+        inline int getSlave() { return _slave_id; };
+
+    private:
+        modbus_t* _ctx;
+    private:
+        std::string _ip;
+        int _port;
+        int _slave_id;
+    };
+};

+ 35 - 0
plc/StdCondition.cpp

@@ -0,0 +1,35 @@
+#include "StdCondition.h"
+
+StdCondition::StdCondition():m_value(false)
+{
+}
+
+StdCondition::StdCondition(bool init):m_value(init)
+{
+}
+
+StdCondition::~StdCondition()
+{
+}
+bool StdCondition::isTrue(StdCondition* scd)
+{
+	if (scd == 0)return false;
+	return scd->m_value;
+}
+
+void StdCondition::Wait()
+{
+	std::unique_lock<std::mutex> loc(m_mutex);
+	m_cv.wait(loc,std::bind(isTrue,this));
+}
+bool StdCondition::WaitFor(unsigned int millisecond)
+{
+	std::unique_lock<std::mutex> loc(m_mutex);
+	return m_cv.wait_for(loc, std::chrono::milliseconds(millisecond), std::bind(isTrue, this));
+}
+void StdCondition::Notify(bool istrue)
+{
+	std::unique_lock<std::mutex> loc(m_mutex);
+	m_value = istrue;
+	m_cv.notify_all();
+}

+ 25 - 0
plc/StdCondition.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include <thread>  
+#include <mutex>  
+#include <chrono>  
+#include <condition_variable>
+
+class StdCondition
+{
+public:
+	StdCondition();
+	StdCondition(bool init);
+	~StdCondition();
+	void Wait();
+	bool WaitFor(unsigned int millisecond);
+	void Notify(bool istrue);
+
+protected:
+	static bool isTrue(StdCondition* scd);
+protected:
+	bool m_value;
+	std::mutex m_mutex;
+	std::condition_variable m_cv;
+};
+

+ 240 - 0
plc/plc_communicator.cpp

@@ -0,0 +1,240 @@
+#include "plc_communicator.h"
+
+// ××××××××××× 构造与析构 ×××××××××××
+Plc_Communicator::Plc_Communicator(const char *ip, int port, int slave_id) : b_plc_initialized(false),
+                                                                             b_plc_is_connected(false),
+                                                                             b_plc_is_updating(false),
+                                                                             p_plc_owner(0),
+                                                                             m_plc_thread(0)
+{
+    m_plc_ip = ip;
+    m_plc_port = port;
+    m_plc_slave_id = slave_id;
+    m_plc_current_error = ERROR_CODE::SUCCESS;
+    m_plc_status_update_timeout = 10000;
+    for (size_t i = 0; i < PLC_REGION_NUM; i++)
+    {
+        m_plc_current_status[i].last_time_point = std::chrono::steady_clock::now();
+        m_plc_current_status[i].current_status = 255;
+        m_plc_current_status[i].cmd = 0;
+    }
+    
+    m_plc_data.resize(PLC_REGION_NUM * PLC_SIGNAL_NUM_PER_REGION);
+    m_plc_current_error = connect();
+    m_plc_cond_exit.Notify(false);
+    m_plc_thread = new std::thread(plc_update_thread, this);
+    b_plc_initialized = true;
+}
+
+Plc_Communicator::~Plc_Communicator()
+{
+    m_plc_cond_exit.Notify(true);
+    if (m_plc_thread)
+    {
+        if (m_plc_thread->joinable())
+            m_plc_thread->join();
+        delete m_plc_thread;
+        m_plc_thread = 0;
+    }
+    disconnect();
+}
+
+// ××××××××××× getters setters ×××××××××××
+bool Plc_Communicator::get_connection()
+{
+    return b_plc_is_connected;
+}
+
+bool Plc_Communicator::get_initialize_status()
+{
+    return b_plc_initialized;
+}
+
+ERROR_CODE Plc_Communicator::set_plc_callback(Command_Callback callback, void *p_owner)
+{
+    if (callback == 0 || p_owner == 0)
+        return ERROR_CODE::PLC_SET_CALLBACK_ERROR;
+    m_plc_callback = callback;
+    p_plc_owner = p_owner;
+    return ERROR_CODE::SUCCESS;
+}
+
+ERROR_CODE Plc_Communicator::set_status_update_timeout(int millisecond){
+    m_plc_status_update_timeout = millisecond;
+    return ERROR_CODE::SUCCESS;
+}
+
+// ××××××××××× 内部调用连接与重连 ×××××××××××
+ERROR_CODE Plc_Communicator::connect()
+{
+    std::lock_guard<std::mutex> lck(m_plc_mutex);
+    int rc = m_plc_wrapper.initialize(m_plc_ip.c_str(), m_plc_port, m_plc_slave_id);
+    switch (rc)
+    {
+    case 0:
+        b_plc_is_connected = true;
+        return ERROR_CODE::SUCCESS;
+    case -1:
+        b_plc_is_connected = false;
+        return ERROR_CODE::PLC_CONNECTION_FAILED;
+    case -2:
+        b_plc_is_connected = false;
+        return ERROR_CODE::PLC_SLAVE_ID_ERROR;
+    case -3:
+        b_plc_is_connected = false;
+        return ERROR_CODE::PLC_IP_PORT_ERROR;
+    default:
+        b_plc_is_connected = false;
+        return ERROR_CODE::PLC_UNKNOWN_ERROR;
+    }
+}
+
+ERROR_CODE Plc_Communicator::disconnect()
+{
+    std::lock_guard<std::mutex> lck(m_plc_mutex);
+    m_plc_wrapper.deinitialize();
+    b_plc_is_connected = false;
+}
+
+// ××××××××××× 外部调用执行任务单 ×××××××××××
+ERROR_CODE Plc_Communicator::execute_task(Task_Base *task)
+{
+}
+
+// ××××××××××× 外部调用获取数据, 终端id[1-6] ×××××××××××
+ERROR_CODE Plc_Communicator::get_plc_data(std::vector<uint16_t> &plc_data, int terminal_id)
+{
+    std::lock_guard<std::mutex> lck(m_plc_mutex);
+    plc_data.clear();
+    if (terminal_id == -1)
+    {
+        plc_data.operator=(m_plc_data);
+    }
+    else if (terminal_id <= PLC_REGION_NUM && terminal_id * PLC_SIGNAL_NUM_PER_REGION <= m_plc_data.size())
+    {
+        for (size_t i = (terminal_id - 1) * PLC_SIGNAL_NUM_PER_REGION; i < terminal_id * PLC_SIGNAL_NUM_PER_REGION; i++)
+        {
+            plc_data.push_back(m_plc_data[i]);
+        }
+        return ERROR_CODE::SUCCESS;
+    }
+    else
+        return ERROR_CODE::PLC_NOT_ENOUGH_DATA_ERROR;
+}
+
+// ××××××××××× 更新线程静态函数 ×××××××××××
+void Plc_Communicator::plc_update_thread(Plc_Communicator *plc_communicator)
+{
+    if (plc_communicator == 0)
+        return;
+    while (!plc_communicator->m_plc_cond_exit.WaitFor(1))
+    {
+        plc_communicator->m_plc_mutex.lock();
+        plc_communicator->b_plc_is_connected = plc_communicator->m_plc_wrapper.is_connected();
+        plc_communicator->m_plc_mutex.unlock();
+        // 判断是否初始化完成
+        if (!plc_communicator->b_plc_initialized)
+            continue;
+        // 断线重连
+        if (!plc_communicator->b_plc_is_connected)
+        {
+            plc_communicator->connect();
+            usleep(1000 * PLC_SLEEP_IN_MILLISECONDS * 10);
+        }
+        else
+        { 
+            // 读取所有数据并更新本地
+            int plc_length_temp = PLC_REGION_NUM * PLC_SIGNAL_NUM_PER_REGION;
+            uint16_t plc_data_temp[plc_length_temp];
+            int rc = plc_communicator->m_plc_wrapper.read_registers(PLC_SIGNAL_BEGIN_OFFSET, plc_length_temp, plc_data_temp);
+            if (rc == 0)
+            {
+                plc_communicator->m_plc_mutex.lock();
+                for (size_t i = 0; i < plc_length_temp; i++)
+                {
+                    plc_communicator->m_plc_data[i] = plc_data_temp[i];
+                    // 读取后检查是否存在指令, 存在则调用回调函数启动外部扫描
+                    if(i%PLC_SIGNAL_NUM_PER_REGION == PLC_LASER_START_ADDR && plc_data_temp[i] != plc_communicator->m_plc_current_status[i].cmd){
+                        plc_communicator->m_plc_current_status[i].cmd = plc_data_temp[i];
+                        if(plc_data_temp[i] == 1){
+                            if(plc_communicator->m_plc_callback!=0 && plc_communicator->p_plc_owner!=0){
+                                plc_communicator->m_plc_callback(i/PLC_SIGNAL_NUM_PER_REGION + 1, plc_communicator->p_plc_owner);
+                            }
+                        }
+                    }
+                }
+            }else{
+                plc_communicator->m_plc_current_error = ERROR_CODE::PLC_READ_FAILED;
+            }
+            plc_communicator->m_plc_mutex.unlock();
+
+            // 写入心跳或当前运行状态
+            for (size_t i = 0; i < PLC_REGION_NUM; i++)
+            {
+                int time_interval = std::chrono::duration_cast<std::chrono::milliseconds>
+                    (std::chrono::steady_clock::now() - plc_communicator->m_plc_current_status[i].last_time_point).count();
+                // 判断超时且非心跳,则转回心跳
+                bool modified = false;
+                if (time_interval > plc_communicator->m_plc_status_update_timeout && plc_communicator->m_plc_current_status[i].current_status < 6)
+                {
+                    plc_communicator->m_plc_current_status[i].current_status = 255;
+                    modified = true;
+                }
+                else
+                {
+                    // 状态切换后写入plc
+                    switch (plc_communicator->m_plc_current_status[i].current_status)
+                    {
+                    case 254:
+                        plc_communicator->m_plc_current_status[i].current_status = 255;
+                        modified = true;
+                        break;
+                    case 255:
+                        plc_communicator->m_plc_current_status[i].current_status = 254;
+                        modified = true;
+                        break;
+                    case 0:
+                        plc_communicator->m_plc_current_status[i].current_status = 254;
+                        modified = true;
+                        break;
+                    case 1:
+                        plc_communicator->m_plc_current_status[i].current_status = 2;
+                        modified = true;
+                        break;
+                    case 2:
+                        break;
+                    case 3:
+                        if(time_interval > 3000)
+                        {
+                            plc_communicator->m_plc_current_status[i].current_status = 254;
+                            modified = true;
+                        }
+                        break;
+                    case 4:
+                        break;
+                    case 5:
+                        break;
+                    default:
+                        break;
+                    }
+                }
+                if(modified && plc_communicator->b_plc_is_connected){
+                    plc_communicator->m_plc_mutex.lock();
+                    // 更新时间
+                    plc_communicator->m_plc_current_status[i].last_time_point = std::chrono::steady_clock::now();
+                    // 写入plc
+                    int address_temp = PLC_SIGNAL_BEGIN_OFFSET + PLC_SIGNAL_NUM_PER_REGION * i + PLC_LASER_STATUS_ADDR;
+                    uint16_t value_temp = plc_communicator->m_plc_current_status[i].current_status;
+                    int rc = plc_communicator->m_plc_wrapper.write_registers(address_temp, 1, &value_temp);
+                    if(rc != 0)
+                        plc_communicator->m_plc_current_error = ERROR_CODE::PLC_WRITE_FAILED;
+                    plc_communicator->m_plc_mutex.unlock();
+                }
+            }
+            
+
+        }
+
+        usleep(1000 * PLC_SLEEP_IN_MILLISECONDS);
+    }
+}

+ 93 - 0
plc/plc_communicator.h

@@ -0,0 +1,93 @@
+#ifndef PLC_COMMUNICATOR_HH
+#define PLC_COMMUNICATOR_HH
+
+#include <iostream>
+#include <string.h>
+#include <mutex>
+#include <vector>
+#include <thread>
+#include <unistd.h>
+#include <chrono>
+
+#include "../error.h"
+#include "../task/task_command_manager.h"
+#include "LibmodbusWrapper.h"
+#include "StdCondition.h"
+
+const int PLC_SIGNAL_BEGIN_OFFSET=2;
+const int PLC_REGION_NUM=6;
+const int PLC_SIGNAL_NUM_PER_REGION=12;
+const int PLC_SLEEP_IN_MILLISECONDS=200;
+
+const int PLC_LASER_START_ADDR = 0;
+const int PLC_LASER_STATUS_ADDR = 1;
+const int PLC_LASER_X_ADDR = 2;
+const int PLC_LASER_Y_ADDR = 3;
+const int PLC_LASER_ANGLE_ADDR = 4;
+const int PLC_LASER_LENGTH_ADDR = 5;
+const int PLC_LASER_WIDTH_ADDR = 6;
+const int PLC_LASER_HEIGHT_ADDR = 7;
+const int PLC_LASER_CORRECTNESS_ADDR = 8;
+const int PLC_LASER_WHEELBASE_ADDR = 9;
+
+typedef ERROR_CODE(*Command_Callback)(int terminal_id, void * p_owner);
+
+// plc通信类,modbus通信
+class Plc_Communicator
+{
+    
+public:
+    Plc_Communicator(const char *ip, int port, int slave_id);
+    ~Plc_Communicator();
+
+    // get set 方法
+    bool get_initialize_status();
+    bool get_connection();
+
+    // 设置plc检测到指令后外部回调函数
+    ERROR_CODE set_plc_callback(Command_Callback callback, void * p_owner);
+    // 执行任务单
+    ERROR_CODE execute_task(Task_Base* task);
+    // 获取实时数据
+    ERROR_CODE get_plc_data(std::vector<uint16_t> &plc_data,int terminal_id=-1);
+    // 设置plc状态更新超时时间
+    ERROR_CODE set_status_update_timeout(int millisecond);
+
+    struct plc_region_status{
+        std::chrono::steady_clock::time_point last_time_point;
+        int current_status;
+        int cmd;
+    };
+
+private:
+    // 读写线程函数
+    static void plc_update_thread(Plc_Communicator* plc_communicator);
+    // 连接函数
+    ERROR_CODE connect();
+    ERROR_CODE disconnect();
+
+private:
+    bool                b_plc_is_connected;     // 指示plc连接状态
+    bool                b_plc_initialized;      // 指示plc是否初始化
+    bool                b_plc_is_updating;      // 指示plc线程在运行
+    void*               p_plc_owner;            // 回调函数所有者句柄
+    Command_Callback    m_plc_callback;         // 回调函数
+
+    std::thread*        m_plc_thread;           // plc更新线程句柄
+    StdCondition        m_plc_cond_exit;        // plc更新线程退出条件控制变量
+    std::mutex          m_plc_mutex;            // plc更新互斥锁,锁住与wrapper相关的所有操作
+    modbus::CLibmodbusWrapper   m_plc_wrapper;  // plc连接与读写封装实例
+
+    std::string         m_plc_ip;               // plc连接ip
+    int                 m_plc_port;             // plc连接端口
+    int                 m_plc_slave_id;         // plc连接id
+    int                 m_plc_status_update_timeout;    // plc状态更新超时时间
+
+    std::vector<uint16_t>   m_plc_data;         // 从plc获取的实时数据
+    ERROR_CODE          m_plc_current_error;    // 当前plc出现的错误
+    // 当前系统状态,实时更新到plc。状态254-255互换,状态1从收到指令开始,紧接着改为状态2,
+    // 之后根据外部传入的task,决定写入3或4,默认3保留3秒,4持续保留直到新指令
+    plc_region_status   m_plc_current_status[PLC_REGION_NUM];   
+};
+
+#endif // !PLC_COMMUNICATOR_HH

+ 26 - 0
plc/plc_task.cpp

@@ -0,0 +1,26 @@
+#include "plc_task.h"
+
+Plc_Task::Plc_Task(){
+    m_task_type = Task_type::PLC_TASK;
+}
+
+Plc_Task::~Plc_Task(){
+
+}
+
+int Plc_Task::init(){
+    m_measure_result.terminal_id = -1;
+    m_measure_result.correctness = false;
+    m_measure_result.x = 0;
+    m_measure_result.y = 0;
+    m_measure_result.angle = 0;
+    m_measure_result.length = 0;
+    m_measure_result.width = 0;
+    m_measure_result.height = 0;
+    m_measure_result.wheel_base = 0;
+    m_task_statu = Task_statu::TASK_CREATED;
+}
+
+ERROR_CODE Plc_Task::set_result(measure_result result){
+    memcpy(&m_measure_result, &result, sizeof(result));
+}

+ 32 - 0
plc/plc_task.h

@@ -0,0 +1,32 @@
+#ifndef PLC_TASK_HH
+#define PLC_TASK_HH
+#include <string.h>
+
+#include "task_command_manager.h"
+#include "../error.h"
+
+class Plc_Task : Task_Base
+{
+public:
+    virtual int init();
+    struct measure_result
+    {
+        int terminal_id;
+        float x;
+        float y;
+        float angle;
+        float length;
+        float width;
+        float height;
+        float wheel_base;
+        bool correctness;
+    };
+    Plc_Task();
+    ~Plc_Task();
+    ERROR_CODE set_result(measure_result result);
+
+private:
+struct measure_result m_measure_result;
+};
+
+#endif // !PLC_TASK_HH