0
$\begingroup$

I am a beginner at ROS and trying to migrate a ROS 1 package to ROS 2. I followed most steps from links 1 and 2. I also commented some lines in package.xml, CMakeLists.txt and my .cpp file which I assume is not needed for now.

When I run colcon build, it comes out with the error:

--- stderr: ros_braccio_opencv_obj_detect_grab                             
/home/sany/ros2_braccio/src/braccio_opencv_ws/src/ros_braccio_opencv_obj_detect_grab/parse_and_publish/parse_and_publish.cpp:8:10: fatal error: std_msgs/msg/MultiArrayLayout.hpp: No such file or directory
    8 | #include "std_msgs/msg/MultiArrayLayout.hpp"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
gmake[2]: *** [CMakeFiles/parse_and_publish.dir/build.make:76: CMakeFiles/parse_and_publish.dir/parse_and_publish/parse_and_publish.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:137: CMakeFiles/parse_and_publish.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
---
Failed   <<< ros_braccio_opencv_obj_detect_grab [3.08s, exited with code 2]

Summary: 0 packages finished [3.54s]
  1 package failed: ros_braccio_opencv_obj_detect_grab
  1 package had stderr output: ros_braccio_opencv_obj_detect_grab

This is the package.xml file. (Commented was mostly the ROS 1 code)

<?xml version="1.0"?>
<!--package-->
<package format="2">
  <name>ros_braccio_opencv_obj_detect_grab</name>
  <version>0.0.0</version>
  <description>The ros_braccio_opencv_obj_detect_grab package</description>

  <maintainer email="[email protected]">stedn</maintainer>
  <license>BSD</license>

  <!--buildtool_depend>catkin</buildtool_depend!-->
  <buildtool_depend>ament_cmake</buildtool_depend>

  <!--run_depend>controller_manager</run_depend>
  <run_depend>diff_drive_controller</run_depend>
  <run_depend>gazebo_ros</run_depend>
  <run_depend>gazebo_ros_control</run_depend>
  <run_depend>joint_state_publisher</run_depend>
  <run_depend>position_controllers</run_depend>
  <run_depend>robot_state_publisher</run_depend>
  <run_depend>rqt_robot_steering</run_depend>
  <run_depend>rviz</run_depend>
  <run_depend>xacro</run_depend!-->

  <depend>rclcpp</depend>
  <depend>std_msgs</depend>

  <depend>controller_manager</depend>
  <depend>diff_drive_controller</depend>
  <!--depend>gazebo_ros</depend!-->
  <!--depend>gazebo_ros_control</depend!-->
  <depend>joint_state_publisher</depend>
  <depend>position_controllers</depend>
  <depend>robot_state_publisher</depend>
  <depend>rqt_robot_steering</depend>
  <!--depend>rviz</depend!-->
  <depend>xacro</depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

This is the CMakeLists.txt (where commented is ROS1 code as previously)

#cmake_minimum_required(VERSION 2.8.3)
cmake_minimum_required(VERSION 3.5)

project(ros_braccio_opencv_obj_detect_grab)

if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

 ## Find catkin and any catkin packages
#find_package(catkin REQUIRED COMPONENTS roscpp sensor_msgs)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(std_msgs REQUIRED)


## Declare a catkin package
#catkin_package()

#include_directories(include ${catkin_INCLUDE_DIRS})
include_directories(include)

add_executable(parse_and_publish parse_and_publish/parse_and_publish.cpp)

#target_link_libraries(parse_and_publish ${catkin_LIBRARIES})
ament_target_dependencies(parse_and_publish
  rclcpp
  std_msgs
  sensor_msgs)

#install(DIRECTORY launch urdf stl rviz parse_and_publish
#  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
install(DIRECTORY launch urdf stl rviz parse_and_publish
  DESTINATION lib/${PROJECT_NAME})
install(DIRECTORY include/
  DESTINATION include)
ament_export_include_directories(include)
ament_export_dependencies(sensor_msgs)

#add_dependencies(parse_and_publish std_msgs)
ament_target_dependencies(parse_and_publish std_msgs)

#catkin_install_python(
#  PROGRAMS scripts/braccio_xy_plane.py
#  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})

install(
  PROGRAMS scripts/braccio_xy_plane.py
  DESTINATION bin
)

ament_package()

This is the .cpp file. (again ROS1 code is commented)

//#include "ros/ros.h"
#include "rclcpp/rclcpp.hpp"

//#include "std_msgs/MultiArrayLayout.h"
//#include "std_msgs/MultiArrayDimension.h"
//#include "std_msgs/UInt8MultiArray.h"
//#include "sensor_msgs/JointState.h"
#include "std_msgs/msg/MultiArrayLayout.hpp"
#include "std_msgs/msg/MultiArrayDimension.hpp"
#include "std_msgs/msg/UInt8MultiArray.hpp"
#include "sensor_msgs/msg/JointState.hpp"

#define PI 3.1416

// Umrechnung Radian->Degree
// pi=180°
// aRadien/pi*180

/**
 * This tutorial demonstrates simple receipt of messages over the ROS system.
 */
uint _DataArray[6];

void chatterCallback(const sensor_msgs::JointState::ConstPtr& msg)
{
  int i=0;
  for(i=0; i<6; i++)
  {
    //ROS_INFO("I heard: [%d]", uint((msg->position[i])/PI*180));
    _DataArray[i]= uint((msg->position[i])/PI*180);
  }
}

int main(int argc, char **argv)
{
  /**
   * The ros::init() function needs to see argc and argv so that it can perform
   * any ROS arguments and name remapping that were provided at the command line.
   * For programmatic remappings you can use a different version of init() which takes
   * remappings directly, but for most command-line programs, passing argc and argv is
   * the easiest way to do it.  The third argument to init() is the name of the node.
   *
   * You must call one of the versions of ros::init() before using any other
   * part of the ROS system.
   */
  //ros::init(argc, argv, "parse_and_publish");
  rclcpp::init(argc, argv);

  /**
   * NodeHandle is the main access point to communications with the ROS system.
   * The first NodeHandle constructed will fully initialize this node, and the last
   * NodeHandle destructed will close down the node.
   */
  //ros::NodeHandle n;
  auto node = rclcpp::Node::make_shared("parse_and_publish");

  /**
   * The subscribe() call is how you tell ROS that you want to receive messages
   * on a given topic.  This invokes a call to the ROS
   * master node, which keeps a registry of who is publishing and who
   * is subscribing.  Messages are passed to a callback function, here
   * called chatterCallback.  subscribe() returns a Subscriber object that you
   * must hold on to until you want to unsubscribe.  When all copies of the Subscriber
   * object go out of scope, this callback will automatically be unsubscribed from
   * this topic.
   *
   * The second parameter to the subscribe() function is the size of the message
   * queue.  If messages are arriving faster than they are being processed, this
   * is the number of messages that will be buffered up before beginning to throw
   * away the oldest ones.
   */
  //ros::Subscriber sub = n.subscribe("joint_states", 6, chatterCallback); not sure if needed

  //ros::Publisher pub = n.advertise<std_msgs::UInt8MultiArray>("joint_array", 6);
  auto pub = node->create_publisher<std_msgs::msg::UInt8MultiArray>("joint_array",6);
  
  //ros::Rate loop_rate(10);
  rclcpp::Rate loop_rate(10);

  while (rclcpp::ok())
  {
    //std_msgs::UInt8MultiArray array;
    std_msgs::msg::UInt8MultiArray array;
    //Clear array
    array.data.clear();

    //for loop, pushing data in the size of the array
    for (int i = 0; i < 6; i++)
    {
    //assign array a random number between 0 and 255.
     array.data.push_back(_DataArray[i]);
    }
    //pub.publish(array);
    pub->publish(array);

    //ros::spinOnce();
    rclcpp::spin_some(node);

    loop_rate.sleep();
  }
  /**
   * ros::spin() will enter a loop, pumping callbacks.  With this version, all
   * callbacks will be called from within this thread (the main one).  ros::spin()
   * will exit when Ctrl-C is pressed, or the node is shutdown by the master.
   */
  

  return 0;
}

I know it is a lot to digest but what should be the reason for not being able to find the MultiArrayLayout.hpp? Maybe a missing line in the package.xml or CMakeLists.txt when migrating from ROS1 to ROS2.

Thanks in advanced!

$\endgroup$

2 Answers 2

0
$\begingroup$

For all the srv/msg naming convention in ROS 2, here is the article.

TL;DR (for your question)

  • If name of file is MultiArrayLayout.msg (alphanumeric characters with an upper camel case name), include name for c++ will be multi_array_layout.hpp
  • Name of the fields must be lowercase alphanumeric characters with underscores for separating words.
$\endgroup$
0
$\begingroup$

In /opt/ros/jazzy/include/std_msgs/std_msgs/msg, there are multi_array_layout.h and multi_array_layout.hpp.

I think naming rule was changed.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.