鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    colcon build编译问题

    已定时 已固定 已锁定 已移动 已解决
    综合问题
    colcon build ros2-humble
    2
    12
    1.2k
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 小鱼小
      小鱼 技术大佬 @yudonghou123
      最后由 编辑

      @yudonghou123 贴下代码,根据过往经验是代码问题

      新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

      yudonghou123Y 2 条回复 最后回复 回复 引用 0
      • yudonghou123Y
        小猴同学 @小鱼
        最后由 编辑

        @小鱼 我又重新写了一个节点,也是一样的错误,只要将ADS协议作为依赖包就出现这个,代码如下

        #include <memory>
        #include "rclcpp/rclcpp.hpp"
        #include "auv_msgs/msg/ctd.hpp"
        #include "../lib/ADS/AdsLib/AdsLib.h"
        #include "../lib/ADS/AdsLib/AdsVariable.h"
        #include "../lib/ADS/AdsLib/AdsNotification.h"
        
        using namespace std::chrono_literals;
        
        class ctd_sensor_pub : public rclcpp::Node
        {
        public:
            ctd_sensor_pub() : Node("ctd_sensor_publisher")
            {
                RCLCPP_INFO(this->get_logger(), "CTD RUNNING");
        
                ctd_publisher_ = this->create_publisher<auv_msgs::msg::CTD>("ctd_data", 100);
                ctd_timer_ = this->create_wall_timer(0.1s, std::bind(&ctd_sensor_pub::ctd_time_callback, this));
            }
        
        private:
            void ctd_time_callback()
            {
                static const AmsNetId remoteNetId{192, 168, 0, 2, 1, 1};
                static const char remoteIpV4[] = "192.168.0.2";
        
                AdsDevice route{remoteIpV4, remoteNetId, AMSPORT_R0_PLC_TC3};
        
                AdsVariable<float> read1Var{route, "Sensor.TDDataChannel[1]"};
                AdsVariable<float> read2Var{route, "Sensor.TDDataChannel[2]"};
                auto ctd_data = auv_msgs::msg::CTD();
                ctd_data.temperature = read1Var;
                ctd_data.pressure = read2Var;
                RCLCPP_INFO(this->get_logger(), "温深仪传送数据为:温度-%f,压力-%f", ctd_data.temperature, ctd_data.pressure);
                ctd_publisher_->publish(ctd_data);
            }
            rclcpp::TimerBase::SharedPtr ctd_timer_;
            rclcpp::Publisher<auv_msgs::msg::CTD>::SharedPtr ctd_publisher_;
        };
        
        int main(int argc, char *argv[])
        {
            rclcpp::init(argc, argv);
            rclcpp::spin(std::make_shared<ctd_sensor_pub>());
            rclcpp::shutdown();
            return 0;
        }
        

        终端输出为:

        Starting >>> auv_msgs
        Finished <<< auv_msgs [0.56s]                     
        Starting >>> auv_localize
        --- stderr: auv_localize                              
        /usr/bin/ld: CMakeFiles/ctd_sensor_pub.dir/src/ctd_sensor_pub.cpp.o: in function `ctd_sensor_pub::ctd_time_callback()':
        /home/user2/auv533_ws/src/auv_localize/src/ctd_sensor_pub.cpp:24: undefined reference to `AmsNetId::AmsNetId(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
        /usr/bin/ld: /home/user2/auv533_ws/src/auv_localize/src/ctd_sensor_pub.cpp:27: undefined reference to `AdsDevice::AdsDevice(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, AmsNetId, unsigned short)'
        /usr/bin/ld: CMakeFiles/ctd_sensor_pub.dir/src/ctd_sensor_pub.cpp.o: in function `AdsVariable<float>::AdsVariable(AdsDevice const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
        /home/user2/auv533_ws/src/auv_localize/src/../lib/ADS/AdsLib/AdsVariable.h:15: undefined reference to `AdsDevice::GetHandle(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
        /usr/bin/ld: CMakeFiles/ctd_sensor_pub.dir/src/ctd_sensor_pub.cpp.o: in function `AdsVariable<float>::Read(unsigned long, void*) const':
        /home/user2/auv533_ws/src/auv_localize/src/../lib/ADS/AdsLib/AdsVariable.h:53: undefined reference to `AdsDevice::ReadReqEx2(unsigned int, unsigned int, unsigned long, void*, unsigned int*) const'
        collect2: error: ld returned 1 exit status
        gmake[2]: *** [CMakeFiles/ctd_sensor_pub.dir/build.make:176:ctd_sensor_pub] 错误 1
        gmake[1]: *** [CMakeFiles/Makefile2:210:CMakeFiles/ctd_sensor_pub.dir/all] 错误 2
        gmake: *** [Makefile:146:all] 错误 2
        ---
        Failed   <<< auv_localize [4.10s, exited with code 2]
        
        Summary: 1 package finished [4.81s]
          1 package failed: auv_localize
          1 package had stderr output: auv_localize
        

        他的这个PLC的通讯库是在这里:ADS通讯协议

        芜湖

        小鱼小 1 条回复 最后回复 回复 引用 0
        • yudonghou123Y
          小猴同学 @小鱼
          最后由 编辑

          @小鱼
          如果是上面那个程序:
          Ads_Interface.h代码为:

          #ifndef HEADER_H_ADS_INTERFACE
          #define HEADER_H_ADS_INTERFACE
          #include <yaml-cpp/yaml.h>
          #include <cstdlib>
          #include "../lib/ADS/AdsLib/standalone/AdsDef.h" 
          #include "../lib/ADS/AdsLib/AdsLib.h"
          #include "../lib/ADS/AdsLib/AdsVariable.h"
          #include <time.h>
          #include <boost/thread/thread.hpp>
          #include <variant>
          #include <mutex>
          #include <stdio.h>
          #include <cstring>
          
          using namespace std;
          class RosAds_Interface
          {
              enum{
                  BOOL,
                  UINT8_T,
                  INT8_T,
                  UINT16_T,
                  INT16_T,
                  UINT32_T,
                  INT32_T,
                  INT64_T,
                  FLOAT,
                  DOUBLE,
                  DATE,
              };
          
          public :
          
            using variant_t = variant<bool, uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, int64_t, float, double, tm>;
          
              /**
               * @brief RosAds_Interface simple consctructor
               */
              RosAds_Interface();
          
              ~RosAds_Interface();
          
              /**
               * @brief adsWriteValue writes on a single variable
               * @param name name of the variable to write on
               * @param value value of the variable to write on
               * @return true if the writing succeded
               * @return false otherwise
               */
              bool adsWriteValue(string name, variant_t value);
          
              /**
               * @brief adsReadValue reads a single variable's value
               * @param varname name of the variable to read
               * @return variant_t value of the variable
               */
              variant_t adsReadValue(string varname);
          
              /**
               * @brief adsReadVariables reads multiple variables' value
               * @param varnames names of the variables to read
               * @return vector<variant_t> values of the variables
               */
              vector<variant_t> adsReadVariables(vector<string> varnames);
          
              /**
               * @brief factory (re)-create an IADS variable
               * @param varname the alias of the variable to (re)-create
               * @return true if the creation succeeded
               */
              bool factory(string varname);
          
              /**
               * @brief convert_type_from_string gets the type from a string
               * @param type the type as string
               * @return the type as int
               * @return -1 if not a type
               */
              int convert_type_from_string(string type);
          
              /**
               * @brief setRemoteNetID set the remote NetID
               * @param netId netID to set as string of type: xxx.xxx.xxx.xxx.xxx.xxx
               */
              void setRemoteNetID(string netId){m_remoteNetId = netId;}
          
              /**
               * @brief getRemoteNetID get the remote NetID
               * @return netId netID parameter
               */
              string getRemoteNetID(){return m_remoteNetId;}
          
              /**
               * @brief setRemoteIPV4 set the remoteIPV4
               * @param address IPV4 to set as string of type: xxx.xxx.xxx.xxx
               */
              void setRemoteIPV4(string address){m_remoteIpV4 = address;}
          
              /**
               * @brief getRemoteIPV4 get the remote IPV4
               * @return IPV4 IPV4 parameter
               */
              string getRemoteIPV4(){return m_remoteIpV4;}
          
              /**
               * @brief setLocalNetID set the local NetID
               * @param netId netID to set as string of type: xxx.xxx.xxx.xxx.xxx.xxx
               */
              void setLocalNetID(string netId){m_localNetId_param = netId;
                                            AdsSetLocalAddress(AmsNetId(m_localNetId_param));}
          
              /**
               * @brief getLocalNetID get the local NetID
               * @return netId netID parameter
               */
              string getLocalNetID(){return m_localNetId_param;}
          
              /**
               * @brief getVariablesMap
               * @return a copy of the variables memory
               */
              map<string, pair<string, variant_t>> getVariablesMap(){return m_variables_map;}
          
              /**
               * @brief updateMemory update the variables memory
               */
              void updateMemory();
          
              /**
               * @brief initRoute initialize a connection to the ADS device
               */
              void initRoute();
          
              /**
               * @brief connectionCheck
               *
               * Tries to get ADS state
               * If the ADS is not running setsm_device state to false, to true otherwise
               * If the ADS is not running or connection failed, tries to establish a new connection
               * If connection was down and is up again, recreates all IADS variables (get the new handles)
               *
               * @return ads state
               */
              int connectionCheck();
          
              /**
               * @brief getState
               * @return true if data published are valid
               * @return false otherwise
               */
              bool getState(){return(m_device_state);}
          
              /**
               * @brief getADSState
               * @return return current ADS state
               */
              int getADSState(){return(m_ads_state);}
          
              /**
               * @brief bindPLcVar creates IADS variables for aliased variables given in configuration file
               * @return true if aliasing succeeded
               * @return false otherwise
               */
              bool bindPLcVar();
          
              /**
               * @brief checkVariableType
               * @param varname the name of the variable to check the type of
               * @return the type of the variable as int
               * @return -1 if variable does not exist
               */
              int checkVariableType(string varname);
          
              /**
               * @brief acquireVariables get all ADS variables from the device
               */
              void acquireVariables(){m_VariableADS = m_route->GetDeviceAdsVariables();}
              /*GetDeviceAdsVariables();}*/
          
              /**
               * @brief setName set the name of the device for configuration
               * @param name the name of the device
               */
              void setName(string name){m_name = name;}
          
              /**
               * @brief setFile set the configuration file the device is configured from
               * @param config_file the full path to the YAML configuration file
               */
              void setFile(string config_file){m_config_file = config_file;}
          
          
          private:
          
              string m_remoteNetId;                                  /*!< the NetID of the ADS device                                                                                     */
              string m_remoteIpV4;                                   /*!< the IPV4 of the ADS device                                                                                      */
              string m_localNetId_param;                             /*!< the local net ID                                                                                                */
              double m_temp;                                         /*!< a temp value for reading a variable value                                                                       */
              string m_name;                                         /*!< the name of the device for configuration                                                                        */
              string m_config_file;                                  /*!< the configuration file to use                                                                                   */
              int m_ads_state;                                       /*!< the last known state of ADS                                                                                     */
          
              AmsNetId* m_AmsNetIdremoteNetId;                       /*!< the NetID structure of the ADS device                                                                           */
              AdsDevice* m_route;                                    /*!< the ADS device route                                                                                            */
              bool m_device_state{true};                             /*!< the last known validity state of the values                                                                     */
          
          
              //Mutex utile pour la communication
              mutex m_ComMutex;                                      /*!< Communication mutex                                                                                             */
              mutex m_MemMutex;                                      /*!< memory mutex                                                                                                    */
          
              map<string,string> m_VariableADS;                      /*!< a map with ADS name as key and the variable type as value */
              map<string,string> m_Alias_map;                        /*!< a map with alias name as key and ADS names as value */
              map<string,pair<int, string>> m_VariableMapping;       /*!< a map with alias name as key and both representation of it's type a value                                       */
              map<string,IAdsVariable*> m_RouteMapping;              /*!< a map with alias name as key and the IADS variable as value                                                     */
              map<string, pair<string, variant_t>> m_variables_map;  /*!< a map with alias name as key and a pair with the type of the variable as string and it's value in it's own type */
              };
          #endif
          
          

          Ads_Interface.cpp代码为:

          #include "Ads_Interface.h"
          
          using namespace std;
          
          /**
           * @brief RosAds_Interface simple consctructor
           */
          RosAds_Interface::RosAds_Interface()
          {
          }
          
          RosAds_Interface::~RosAds_Interface()
          {
            if(m_route)
            {
              delete m_route;
            }
            if(m_AmsNetIdremoteNetId)
            {
              delete m_AmsNetIdremoteNetId;
            }
          
            for(map<string,IAdsVariable*>::iterator it = m_RouteMapping.begin(); it != m_RouteMapping.end(); ++it)
            {
               delete it->second;
            }
          }
          
          /**
           * @brief adsWriteValue writes on a single variable
           * @param name name of the variable to write on
           * @param value value of the variable to write on
           * @return true if the writing succeded
           * @return false otherwise
           */
          bool RosAds_Interface::adsWriteValue(string name, variant_t value){
          
            int varType = checkVariableType(name);
            bool dataCorrect = true;
            bool bresult = true;
            auto no_issue = true;
            if( m_VariableMapping.find(name) == m_VariableMapping.end()){
              dataCorrect =  false;
              bresult =  false;
            }
            else if (m_VariableMapping[name].first == varType && m_device_state)
            {
              m_ComMutex.lock();
              m_MemMutex.lock();
              try
              {
                switch(m_VariableMapping[name].first)
                {
                case BOOL:
                {
                    *m_RouteMapping[name] = get<bool>(value);
                    break;
                }
                case UINT8_T:
                {
                    *m_RouteMapping[name] = get<uint8_t>(value);
                    break;
                }
                case INT8_T:
                {
                    *m_RouteMapping[name] = get<int8_t>(value);
                    break;
                }
                case UINT16_T:
                {
                    *m_RouteMapping[name] = get<uint16_t>(value);
                    break;
                }
                case INT16_T:
                {
                    *m_RouteMapping[name] = get<int16_t>(value);
                    break;
                }
                case UINT32_T:
                {
                    *m_RouteMapping[name] = get<uint32_t>(value);
                    break;
                }
                case INT32_T:
                {
                    *m_RouteMapping[name] = get<int32_t>(value);
                    break;
                }
                case INT64_T:
                {
                    *m_RouteMapping[name] = get<int64_t>(value);
                    break;
                }
                case FLOAT:
                {
                    *m_RouteMapping[name] = get<float>(value);
                    break;
                }
                case DOUBLE:
                {
                    *m_RouteMapping[name] = get<double>(value);
                    break;
                }
                case DATE:
                {
                    tm temp = get<tm>(value);
                    *m_RouteMapping[name] = mktime(&temp);
                    break;
                }
                default:
                {
                      no_issue = false;
                }
                }
              }
              catch(AdsException e)
              {
                  no_issue = false;
              }
              m_MemMutex.unlock();
              m_ComMutex.unlock();
            }
            else
            {
              factory(name);
            }
            if(!no_issue){
                factory(name);
            }
          
            if(!dataCorrect) {
              bresult =  false;
            }
            return bresult;
          }
          
          /**
           * @brief adsReadValue reads a single variable's value
           * @param varName name of the variable to read
           * @return variant_t value of the variable
           */
          RosAds_Interface::variant_t RosAds_Interface::adsReadValue(string name)
          {
            variant_t result;
          
            if(m_RouteMapping.find(name) != m_RouteMapping.end())
            {
                auto no_issue = true;
                m_ComMutex.lock();
                m_MemMutex.lock();
                if(m_device_state)
                {
                    try
                    {
                        if(m_RouteMapping[name])
                        {
                            m_RouteMapping[name]->ReadValue(&m_temp);
          
                            switch(m_VariableMapping[name].first)
                            {
                            case BOOL:
                            {
                                result =(bool)m_temp;
                                break;
                            }
                            case UINT8_T:
                            {
                                result = (uint8_t)m_temp;
                                break;
                            }
                            case INT8_T:
                            {
                                result = (int8_t)m_temp;
                                break;
                            }
                            case UINT16_T:
                            {
                                result = (uint16_t)m_temp;
                                break;
                            }
                            case INT16_T:
                            {
                                result = (int16_t)m_temp;
                                break;
                            }
                            case UINT32_T:
                            {
                                result = (uint32_t)m_temp;
                                break;
                            }
                            case INT32_T:
                            {
                                result = (int32_t)m_temp;
                                break;
                            }
                            case INT64_T:
                            {
                                result = (int64_t)m_temp;
                                break;
                            }
                            case FLOAT:
                            {
                                result = (float)m_temp;
                                break;
                            }
                            case DOUBLE:
                            {
                                result = (double)m_temp;
                                break;
                            }
                            case DATE:
                            {
                                result = (uint32_t)m_temp;
                                break;
                            }
                            default:
                            {
          
                            }
                            }
                        }
                        else
                        {
                            no_issue = false;
                        }
                        }
                        catch(...)
                        {
                          no_issue = false;
                        }
                }
                m_MemMutex.unlock();
                m_ComMutex.unlock();
                if(!no_issue)
                {
                    factory(name);
                }
            }
            return result;
          }
          
          /**
           * @brief adsReadVariables reads multiple variables' value
           * @param varNames names of the variables to read
           * @return vector<variant_t> values of the variables
           */
          vector<RosAds_Interface::variant_t> RosAds_Interface::adsReadVariables(vector<string> varNames)
          {
            vector<variant_t> result;
          
            for (auto& name: varNames)
            {
              result.push_back(adsReadValue(name));
            }
          
            return result;
          }
          
          /**
           * @brief factory (re)-create an IADS variable
           * @param varName the alias of the variable to (re)-create
           * @return true if the creation succeeded
           */
          bool RosAds_Interface::factory(string  varName)
          {
              bool result = false;
              auto no_issue = true;
              m_MemMutex.lock();
              try {
                  string type = m_VariableADS[m_Alias_map[varName]];
                  do{
                      if(m_RouteMapping[varName])
                      {
                          delete m_RouteMapping[varName];
                      }
                    if(type == "BOOL"){
                      m_RouteMapping[varName] = new AdsVariable<bool>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "BYTE" || type == "USINT"){
                      m_RouteMapping[varName] = new AdsVariable<uint8_t>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "SINT"){
                      m_RouteMapping[varName] = new AdsVariable<int8_t>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "WORD" || type == "UINT"){
                      m_RouteMapping[varName] = new AdsVariable<uint16_t>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "INT"){
                      m_RouteMapping[varName] = new AdsVariable<int16_t>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "DWORD" || type == "UDINT" || type == "DATE" || type == "TIME" || type == "TIME_OF_DAY" || type == "LTIME"){
                      m_RouteMapping[varName] = new AdsVariable<uint32_t>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "DINT"){
                      m_RouteMapping[varName] = new AdsVariable<int32_t>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "LINT"){
                      m_RouteMapping[varName] = new AdsVariable<int64_t>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "REAL"){
                      m_RouteMapping[varName] = new AdsVariable<float>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                    if(type == "LREAL"){
                      m_RouteMapping[varName] = new AdsVariable<double>(*m_route, m_Alias_map[varName]);
                      result = true;
                      break;
                    }
                  }
                  while(false);
              } catch (...) {
                  no_issue = false;
              }
              m_MemMutex.unlock();
          
              if(!no_issue){
                  m_ads_state = false;
                  connectionCheck();
              }
          
              return result;
          }
          
          /**
           * @brief convert_type_from_string gets the type from a string
           * @param type the type as string
           * @return the type as int
           * @return -1 if not a type
           */
          int RosAds_Interface::convert_type_from_string(string type)
          {
             int result = -1;
             do
             {
                 if(type == "BOOL")
                 {
                     result = BOOL;
                     break;
                 }
                 if(type == "BYTE" || type == "USINT")
                 {
                     result = UINT8_T;
                     break;
                 }
                 if(type == "SINT")
                 {
                     result = INT8_T;
                     break;
                 }
                 if(type == "WORD" || type == "UINT")
                 {
                     result = UINT16_T;
                     break;
                 }
                 if(type == "INT")
                 {
                     result = INT16_T;
                     break;
                 }
                 if(type == "DWORD" || type == "UDINT")
                 {
                     result = UINT32_T;
                     break;
                 }
                 if(type == "DINT")
                 {
                     result = INT32_T;
                     break;
                 }
                 if(type == "LINT")
                 {
                     result = INT64_T;
                     break;
                 }
                 if(type == "REAL")
                 {
                     result = FLOAT;
                     break;
                 }
                 if(type == "LREAL")
                 {
                     result = DOUBLE;
                     break;
                 }
                 if(type == "DATE")
                 {
                     result = DATE;
                     break;
                 }
             }
             while(false);
             return result;
          }
          
          /**
           * @brief updateMemory update the variables memory
           */
          void RosAds_Interface::updateMemory()
          {
              for(auto &[name, pair]: m_variables_map)
              {
                  pair.second = adsReadValue(name);
              }
          }
          
          /**
           * @brief initRoute initialize a connection to the ADS device
           */
          void RosAds_Interface::initRoute()
          {
            m_AmsNetIdremoteNetId= new AmsNetId(m_remoteNetId);
            m_route = new AdsDevice(m_remoteIpV4.c_str(),*m_AmsNetIdremoteNetId, AMSPORT_R0_PLC_TC3);
          }
          
          /**
           * @brief connectionCheck
           *
           * Tries to get ADS state
           * If the ADS is not running setsm_device state to false, to true otherwise
           * If the ADS is not running or connection failed, tries to establish a new connection
           * If connection was down and is up again, recreates all IADS variables (get the new handles)
           *
           * @return ads state
           */
          int RosAds_Interface::connectionCheck()
          {
              auto result = false;
              AdsDeviceState test;
              auto temp_state = m_device_state;
              m_ComMutex.lock();
              try {
                  test = m_route->GetState();
                  result = (test.ads == ADSSTATE_RUN);
                  m_ads_state = (uint16_t)test.ads;
              } catch (...) {
                  m_ads_state = ADSSTATE_INVALID;
              }
          
              if (!result) //recovery
              {
                  if(m_route)
                  {
                    delete m_route;
                  }
                  if(m_AmsNetIdremoteNetId)
                  {
                    delete m_AmsNetIdremoteNetId;
                  }
                  initRoute();
              }
              m_ComMutex.unlock();
          
              if(result && !temp_state) //recreate ADSVariables if connexion is re-established
              {
                  acquireVariables();
                  for(auto &[name, alias]: m_VariableMapping)
                  {
                      factory(name);
                  }
              }
          
              m_device_state = result;
          
              return (int)test.ads;
          }
          
          /**
           * @brief bindPLcVar creates IADS variables for aliased variables given in configuration file
           * @return true if aliasing succeeded
           * @return false otherwise
           */
          bool RosAds_Interface::bindPLcVar()
          {
            bool bresult = false;
            YAML::Node config = YAML::LoadFile(m_config_file);
            if (config[m_name])
            {
          
              //Read each alias with corresponding ADS name
              for(YAML::const_iterator element=config[m_name]["variables"].begin();element!=config[m_name]["variables"].end();++element)
              {
                string adsName = element->first.as<string>();
                string alias = element->second.as<string>();
                //Check if ADS name is part of downloaded PLC ADS list
                if ( m_VariableADS.find(adsName) == m_VariableADS.end() )
                {
                    continue;
                }
          
                string type = m_VariableADS[adsName];
                m_VariableMapping[alias] = pair<int, string>(convert_type_from_string(type), type);
                m_variables_map[alias] = pair<string, variant_t>(type, variant_t());
                m_Alias_map[alias] = adsName;
                factory(alias);
              }
              bresult = true;
            }
            else
            {
          
            }
              return bresult;
          }
          
          /**
           * @brief checkVariableType
           * @param varName the name of the variable to check the type of
           * @return the type of the variable as int
           * @return -1 if variable does not exist
           */
          int RosAds_Interface::checkVariableType(string varName){
            int varType = -1;
              map<string,pair<int, string>>::iterator it;
               it= m_VariableMapping.find(varName);
            if(it != m_VariableMapping.end())
            {
              varType = it->second.first;
            }
            return varType;
          }
          
          

          他其中依赖包的AdsVariable.h代码为:

          // SPDX-License-Identifier: MIT
          /**
             Copyright (c) 2020 - 2022 Beckhoff Automation GmbH & Co. KG
           */
          
          #pragma once
          
          #include "AdsDevice.h"
          #include "cstring"
          
          
          struct IAdsVariable {
          
            virtual void operator=(const bool& value){}
            virtual void operator=(const uint8_t& value){}
            virtual void operator=(const int8_t& value){}
            virtual void operator=(const uint16_t& value){}
            virtual void operator=(const int16_t& value){}
            virtual void operator=(const uint32_t& value){}
            virtual void operator=(const int32_t& value){}
            virtual void operator=(const uint64_t& value){}
            virtual void operator=(const int64_t& value){}
            virtual void operator=(const float& value){}
            virtual void operator=(const double& value){}
           
            virtual void ReadValue(void *res){}
            virtual ~IAdsVariable(){}
          }; 
          
          
          
          
          template<typename T>
          struct AdsVariable  : public IAdsVariable{
              AdsVariable(const AdsDevice& route, const std::string& symbolName)
                  : m_Route(route),
                  m_IndexGroup(ADSIGRP_SYM_VALBYHND),
                  m_Handle(route.GetHandle(symbolName))
              {}
          
              AdsVariable(const AdsDevice& route, const uint32_t group, const uint32_t offset)
                  : m_Route(route),
                  m_IndexGroup(group),
                  m_Handle(route.GetHandle(offset))
              {}
          
              operator T() const
              {
                  T buffer;
                  Read(sizeof(buffer), &buffer);
                  return buffer;
              }
          
              void ReadValue(void *res) override
              {
          	T buffer;
              Read(sizeof(buffer), &buffer);
              memcpy(res, &buffer, sizeof(T));
              }
          
              void operator=(const T& value) override
              {
                  Write(sizeof(T), &value);
              }
          
              template<typename U, size_t N>
              operator std::array<U, N>() const
              {
                  std::array<U, N> buffer;
                  Read(sizeof(U) * N, buffer.data());
                  return buffer;
              }
          
              template<typename U, size_t N>
              void operator=(const std::array<U, N>& value) const
              {
                  Write(sizeof(U) * N, value.data());
              }
          
              void Read(const size_t size, void* data) const
              {
                  uint32_t bytesRead = 0;
                  auto error = m_Route.ReadReqEx2(m_IndexGroup,
                                                  *m_Handle,
                                                  size,
                                                  data,
                                                  &bytesRead);
          
                  if (error || (size != bytesRead)) {
                      throw AdsException(error);
                  }
              }
          
              void Write(const size_t size, const void* data) const
              {
                  auto error = m_Route.WriteReqEx(m_IndexGroup, *m_Handle, size, data);
                  if (error) {
                      throw AdsException(error);
                  }
              }
          private:
              const AdsDevice& m_Route;
              const uint32_t m_IndexGroup;
              const AdsHandle m_Handle;
          };
          

          代码有点多,已经困扰我好几天了,我原先以为gcc和G++的版本导致的,但是我看了看gcc和g++的版本都是11.3一样的,我用的这个倍服的PLC提供的通讯库和我ROS2结合的时候感觉问题好多,万分感激

          芜湖

          1 条回复 最后回复 回复 引用 0
          • 小鱼小
            小鱼 技术大佬 @yudonghou123
            最后由 编辑

            @yudonghou123 在 colcon build编译问题 中说:

            #include "../lib/ADS/AdsLib/AdsLib.h"
            #include "../lib/ADS/AdsLib/AdsVariable.h"
            #include "../lib/ADS/AdsLib/AdsNotification.h"

            把前面的..去掉,修改CmakeLists.txt 将lib文件夹添加进去,然后
            #include "ADS/AdsLib/AdsNotification.h" 引用

            新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

            yudonghou123Y 3 条回复 最后回复 回复 引用 0
            • yudonghou123Y
              小猴同学 @小鱼
              最后由 编辑

              @小鱼 好的,大佬,我通过add_subdirectory(lib/ADS/AdsLib)添加好像不管用

              cmake_minimum_required(VERSION 3.8)
              project(auv_localize)
              
              if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
                add_compile_options(-Wall -Wextra -Wpedantic)
              endif()
              find_package(Threads REQUIRED)
              set(CMAKE_BUILD_TYPE debug)
              add_subdirectory(lib/ADS/AdsLib)
              
              find_package(ament_cmake REQUIRED)
              find_package(rclcpp REQUIRED)
              find_package(auv_msgs REQUIRED)
              find_package(geometry_msgs REQUIRED)
              find_package(std_msgs REQUIRED)
              find_package(message_filters REQUIRED)
              
              
              add_executable(localize_sensor_info_pub src/localize_sensor_info_pub.cpp)
              target_include_directories(localize_sensor_info_pub PUBLIC
                $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
                $<INSTALL_INTERFACE:include>)
              target_compile_features(localize_sensor_info_pub PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
              ament_target_dependencies(
                localize_sensor_info_pub
                "rclcpp"
                "std_msgs"
                "auv_msgs"
              )
              
              add_executable(sensor_info_sub src/sensor_info_sub.cpp)
              target_include_directories(sensor_info_sub PUBLIC
                $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
                $<INSTALL_INTERFACE:include>)
              target_compile_features(sensor_info_sub PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
              ament_target_dependencies(
                sensor_info_sub
                "rclcpp"
                "std_msgs"
                "auv_msgs"
                "message_filters"
              )
              
              add_executable(ctd_sensor_pub src/ctd_sensor_pub.cpp)
              target_include_directories(ctd_sensor_pub PUBLIC
                $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
                $<INSTALL_INTERFACE:include>)
              target_compile_features(ctd_sensor_pub PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
              ament_target_dependencies(
                ctd_sensor_pub
                "rclcpp"
                "std_msgs"
                "auv_msgs"
                "message_filters"
              )
              
              install(TARGETS localize_sensor_info_pub ctd_sensor_pub
                DESTINATION lib/${PROJECT_NAME})
              install(TARGETS ctd_sensor_pub
                ARCHIVE DESTINATION lib
                LIBRARY DESTINATION lib
                RUNTIME DESTINATION lib/${PROJECT_NAME})
              
              #install(DIRECTORY
              # config
              # DESTINATION share/${PROJECT_NAME}/)
              
              if(BUILD_TESTING)
                find_package(ament_lint_auto REQUIRED)
                # the following line skips the linter which checks for copyrights
                # comment the line when a copyright and license is added to all source files
                set(ament_cmake_copyright_FOUND TRUE)
                # the following line skips cpplint (only works in a git repo)
                # comment the line when this package is in a git repo and when
                # a copyright and license is added to all source files
                set(ament_cmake_cpplint_FOUND TRUE)
                ament_lint_auto_find_test_dependencies()
              endif()
              
              ament_package()
              

              芜湖

              1 条回复 最后回复 回复 引用 0
              • yudonghou123Y
                小猴同学 @小鱼
                最后由 yudonghou123 编辑

                @小鱼 成功了,多谢大佬,需要在cmakelist文件里添加一个add_dependencies(ros_ads_node ads)以及添加一个target_link_libraries,cmakelist文件如下:

                cmake_minimum_required(VERSION 3.8)
                project(auv_localize)
                
                if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
                  add_compile_options(-Wall -Wextra -Wpedantic)
                endif()
                
                set(THREADS_PREFER_PTHREAD_FLAG ON)
                
                find_package(Threads REQUIRED)
                
                set(CMAKE_BUILD_TYPE debug)
                add_subdirectory(lib/ADS/AdsLib)
                
                
                find_package(ament_cmake REQUIRED)
                find_package(rclcpp REQUIRED)
                find_package(auv_msgs REQUIRED)
                find_package(geometry_msgs REQUIRED)
                find_package(std_msgs REQUIRED)
                find_package(message_filters REQUIRED)
                
                add_executable(localize_sensor_info_pub src/localize_sensor_info_pub.cpp)
                target_include_directories(localize_sensor_info_pub PUBLIC
                  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
                  $<INSTALL_INTERFACE:include>)
                target_compile_features(localize_sensor_info_pub PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
                ament_target_dependencies(
                  localize_sensor_info_pub
                  "rclcpp"
                  "std_msgs"
                  "auv_msgs"
                )
                
                add_executable(sensor_info_sub src/sensor_info_sub.cpp)
                target_include_directories(sensor_info_sub PUBLIC
                  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
                  $<INSTALL_INTERFACE:include>)
                target_compile_features(sensor_info_sub PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
                ament_target_dependencies(
                  sensor_info_sub
                  "rclcpp"
                  "std_msgs"
                  "auv_msgs"
                  "message_filters"
                )
                add_executable(ctd_sensor_pub src/ctd_sensor_pub.cpp)
                add_dependencies(ctd_sensor_pub  ads)
                target_compile_features(ctd_sensor_pub PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
                ament_target_dependencies(
                  ctd_sensor_pub
                  "rclcpp"
                  "std_msgs"
                  "auv_msgs"
                  "message_filters"
                )
                target_include_directories(ctd_sensor_pub PUBLIC
                  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
                  $<INSTALL_INTERFACE:include>)
                
                target_link_libraries(ctd_sensor_pub ${ament_LIBRARIES} ads -lpthread)
                
                install(TARGETS localize_sensor_info_pub ctd_sensor_pub
                  DESTINATION lib/${PROJECT_NAME})
                install(TARGETS ctd_sensor_pub
                  ARCHIVE DESTINATION lib
                  LIBRARY DESTINATION lib
                  RUNTIME DESTINATION lib/${PROJECT_NAME})
                 
                #install(DIRECTORY
                # config
                # DESTINATION share/${PROJECT_NAME}/)
                
                if(BUILD_TESTING)
                  find_package(ament_lint_auto REQUIRED)
                  # the following line skips the linter which checks for copyrights
                  # comment the line when a copyright and license is added to all source files
                  set(ament_cmake_copyright_FOUND TRUE)
                  # the following line skips cpplint (only works in a git repo)
                  # comment the line when this package is in a git repo and when
                  # a copyright and license is added to all source files
                  set(ament_cmake_cpplint_FOUND TRUE)
                  ament_lint_auto_find_test_dependencies()
                endif()
                
                ament_package()
                
                

                终于编译成功了,多谢大佬,但是大佬,我在ros2 run这个节点时出现这样一个问题:

                ros2 run auv_localize ctd_sensor_pub
                

                终端输出:

                /home/user2/auv533_ws/install/auv_localize/lib/auv_localize/ctd_sensor_pub: error while loading shared libraries: libads.so: cannot open shared object file: No such file or directory
                [ros2run]: Process exited with failure 127
                

                希望大佬提醒一下,万分感激

                芜湖

                小鱼小 1 条回复 最后回复 回复 引用 0
                • yudonghou123Y yudonghou123 将这个主题标记为已解决,在
                • yudonghou123Y yudonghou123 将这个主题标记为未解决,在
                • yudonghou123Y
                  小猴同学 @小鱼
                  最后由 yudonghou123 编辑

                  @小鱼 大佬,在编译时出现这样的问题了

                  /home/user2/auv533_ws/install/auv_localize/lib/auv_localize/ctd_sensor_pub: error while loading shared libraries: libads.so: cannot open shared object file: No such file or directory
                  [ros2run]: Process exited with failure 127
                  

                  我以为是依赖不在路径上,所以我在bashrc上添加这个lib的路径:

                  export LD_LIBRARY_PATH=/home/user2/auv533_ws/src/auv_localize/lib:$LD_LIBRARY_PATH
                  

                  程序的结构如下:
                  截图 2023-02-07 21-23-00.png
                  在lib文件夹里编译了ADS的PLC通讯包,结果显示这个包不存在,难道不是依赖包文件的路径问题吗?还是说我cmakelist文件(代码在上面的聊天里)缺少一个配置,我看github上关于其都是在src路径下建立一个lib文件,然后将ADS通讯库放入进行编译,但是到我这里就出现这样的问题了,请大佬提醒一下,万分感激

                  芜湖

                  1 条回复 最后回复 回复 引用 0
                  • 小鱼小
                    小鱼 技术大佬 @yudonghou123
                    最后由 编辑

                    @yudonghou123 在 colcon build编译问题 中说:

                    /home/user2/auv533_ws/install/auv_localize/lib/auv_localize/ctd_sensor_pub

                    ldd /home/user2/auv533_ws/install/auv_localize/lib/auv_localize/ctd_sensor_pub 看一下,是不是那个ads库没link上,这个库是静态库还是动态库还是源码引入的

                    新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

                    yudonghou123Y 2 条回复 最后回复 回复 引用 0
                    • yudonghou123Y
                      小猴同学 @小鱼
                      最后由 编辑

                      @小鱼 在 colcon build编译问题 中说:

                      ldd /home/user2/auv533_ws/install/auv_localize/lib/auv_localize/ctd_sensor_pub

                      通过您提供的命令查找结果如下:

                      linux-vdso.so.1 (0x00007ffeb5ad1000)
                      	libauv_msgs__rosidl_typesupport_cpp.so => not found
                      	libads.so => not found
                      	librclcpp.so => /opt/ros/humble/lib/librclcpp.so (0x00007f21a8c1e000)
                      	librcl.so => /opt/ros/humble/lib/librcl.so (0x00007f21a8bde000)
                      	librmw.so => /opt/ros/humble/lib/librmw.so (0x00007f21a8bd2000)
                      	libtracetools.so => /opt/ros/humble/lib/libtracetools.so (0x00007f21a8bcd000)
                      	librcutils.so => /opt/ros/humble/lib/librcutils.so (0x00007f21a8bb5000)
                      	libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f21a898b000)
                      	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f21a896b000)
                      	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f21a8741000)
                      	liblibstatistics_collector.so => /opt/ros/humble/lib/liblibstatistics_collector.so (0x00007f21a873a000)
                      	librcl_interfaces__rosidl_typesupport_cpp.so => /opt/ros/humble/lib/librcl_interfaces__rosidl_typesupport_cpp.so (0x00007f21a872f000)
                      	librcl_yaml_param_parser.so => /opt/ros/humble/lib/librcl_yaml_param_parser.so (0x00007f21a8723000)
                      	librosgraph_msgs__rosidl_typesupport_cpp.so => /opt/ros/humble/lib/librosgraph_msgs__rosidl_typesupport_cpp.so (0x00007f21a871e000)
                      	libstatistics_msgs__rosidl_typesupport_cpp.so => /opt/ros/humble/lib/libstatistics_msgs__rosidl_typesupport_cpp.so (0x00007f21a8719000)
                      	librmw_implementation.so => /opt/ros/humble/lib/librmw_implementation.so (0x00007f21a870a000)
                      	libament_index_cpp.so => /opt/ros/humble/lib/libament_index_cpp.so (0x00007f21a86ff000)
                      	librcl_logging_interface.so => /opt/ros/humble/lib/librcl_logging_interface.so (0x00007f21a86fa000)
                      	librcpputils.so => /opt/ros/humble/lib/librcpputils.so (0x00007f21a86ec000)
                      	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f21a8605000)
                      	/lib64/ld-linux-x86-64.so.2 (0x00007f21a8e94000)
                      	librcl_logging_spdlog.so => /opt/ros/humble/lib/librcl_logging_spdlog.so (0x00007f21a85fe000)
                      	librcl_interfaces__rosidl_typesupport_c.so => /opt/ros/humble/lib/librcl_interfaces__rosidl_typesupport_c.so (0x00007f21a85f3000)
                      	librcl_interfaces__rosidl_generator_c.so => /opt/ros/humble/lib/librcl_interfaces__rosidl_generator_c.so (0x00007f21a85d7000)
                      	librosidl_runtime_c.so => /opt/ros/humble/lib/librosidl_runtime_c.so (0x00007f21a85cc000)
                      	librosidl_typesupport_cpp.so => /opt/ros/humble/lib/librosidl_typesupport_cpp.so (0x00007f21a85c6000)
                      	libyaml.so => /opt/ros/humble/lib/libyaml.so (0x00007f21a85a4000)
                      	libspdlog.so.1 => /lib/x86_64-linux-gnu/libspdlog.so.1 (0x00007f21a8527000)
                      	librosidl_typesupport_c.so => /opt/ros/humble/lib/librosidl_typesupport_c.so (0x00007f21a8521000)
                      	libbuiltin_interfaces__rosidl_generator_c.so => /opt/ros/humble/lib/libbuiltin_interfaces__rosidl_generator_c.so (0x00007f21a851c000)
                      	libfmt.so.8 => /lib/x86_64-linux-gnu/libfmt.so.8 (0x00007f21a84fb000)
                      
                      

                      我觉得是通过源码引入的,因为我在github上下载了这个ADS库,然后在src文件夹中建立了一个lib文件夹,将其放入了

                      芜湖

                      1 条回复 最后回复 回复 引用 0
                      • yudonghou123Y
                        小猴同学 @小鱼
                        最后由 编辑

                        @小鱼 在 colcon build编译问题 中说:

                        ldd /home/user2/auv533_ws/install/auv_localize/lib/auv_localize/ctd_sensor_pub

                        成功了,我在创建新的节点时忘记首先对通讯库进行编译了,人麻了,多谢大佬的指点,万分感激

                        芜湖

                        1 条回复 最后回复 回复 引用 0
                        • yudonghou123Y yudonghou123 将这个主题标记为已解决,在
                        • 第一个帖子
                          最后一个帖子
                        皖ICP备16016415号-7
                        Powered by NodeBB | 鱼香ROS