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

    colcon build编译问题

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

      @yudonghou123 函数其实都存在,但是一直报这个错误

      芜湖

      小鱼小 1 条回复 最后回复 回复 引用 0
      • 小鱼小
        小鱼 技术大佬 @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