0
$\begingroup$

Rosanswers logo

Instead of the normal std_msgs::string, i want to use std_msgs::Float32 in the demo_nodes_cpp talker example.

is it possible to directly replace string with float32 as both belong to std_msgs or do i need to create a new custom message definition ?

I want to do something like this :

class Talker : public rclcpp::Node
   {
   public:
   explicit Talker(const std::string & topic_name)
   : Node("talker")
   {
   msg_ = std::make_shared<std_msgs::msg::Float32>();

  // Create a function for when messages are to be sent.
  auto publish_message =
  [this]() -> void
  {
count_++;
if (count_ <= 50){
    msg_->data = 100;}

if (count_ > 50)
{
    msg_->data = 0;}
    RCLCPP_INFO(this->get_logger(), "Publishing: '%f'", msg_->data)

    // Put the message into a queue to be processed by the middleware.
    // This call is non-blocking.
    pub_->publish(msg_);
  };

Is this possible ?

This is the actual code:

#include <chrono>
#include <cstdio>
#include <memory>
#include <string>


#include "rclcpp/rclcpp.hpp"
#include "rcutils/cmdline_parser.h"

#include "std_msgs/msg/string.hpp"
#include "std_msgs/msg/float32.hpp"

using namespace std::chrono_literals;

void print_usage()
{
  printf("Usage for talker app:\n");
  printf("talker [-t topic_name] [-h]\n");
  printf("options:\n");
  printf("-h : Print this help function.\n");
  printf("-t topic_name : Specify the topic on which to publish. Defaults to chatter.\n");
}

// Create a Talker class that subclasses the generic rclcpp::Node base class.
// The main function below will instantiate the class as a ROS node.
class Source : public rclcpp::Node
{
public:
  explicit Source(const std::string & topic_name)
  : Node("source")
  {
    heatflow_source = std::make_shared<std_msgs::msg::Float32>();

    // Create a function for when messages are to be sent.
    auto publish_message =
      [this]() -> void
      {
    count_++;
    if (count_ <= 50){
        heatflow_source->data = 100;}

    if (count_ > 50)
    {
        heatflow_source->data = 0.0;}
        RCLCPP_INFO(this->get_logger(), "Publishing: '%f'", heatflow_source->data)

        // Put the message into a queue to be processed by the middleware.
        // This call is non-blocking.
        pub_->publish(heatflow_source);
      };

    // Create a publisher with a custom Quality of Service profile.
    rmw_qos_profile_t custom_qos_profile = rmw_qos_profile_default;
    custom_qos_profile.depth = 7;
    pub_ = this->create_publisher<std_msgs::msg::Float32>(topic_name, custom_qos_profile); //edited

    // Use a timer to schedule periodic message publishing.
    timer_ = this->create_wall_timer(1s, publish_message);
  }

private:
  size_t count_ = 1;
  std::shared_ptr<std_msgs::msg::Float32> heatflow_source;
  rclcpp::Publisher<std_msgs::msg::Float32>::SharedPtr pub_;
  rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char * argv[])
{
  // Force flush of the stdout buffer.
  // This ensures a correct sync of all prints
  // even when executed simultaneously within the launch file.
  setvbuf(stdout, NULL, _IONBF, BUFSIZ);

  if (rcutils_cli_option_exist(argv, argv + argc, "-h")) {
    print_usage();
    return 0;
  }

  // Initialize any global resources needed by the middleware and the client library.
  // You must call this before using any other part of the ROS system.
  // This should be called once per process.
  rclcpp::init(argc, argv);

  // Parse the command line options.
  auto topic = std::string("heatflow_source");
  if (rcutils_cli_option_exist(argv, argv + argc, "-t")) {
    topic = std::string(rcutils_cli_get_option(argv, argv + argc, "-t"));
  }

  // Create a node.
  auto node = std::make_shared<Source>(topic);

  // spin will block until work comes in, execute work as it becomes available, and keep blocking.
  // It will only be interrupted by Ctrl-C.
  rclcpp::spin(node);

  rclcpp::shutdown();
  return 0;
}

I still get an error here :

error: no matching function for call to ‘std::__shared_ptrrclcpp::Publisher<std_msgs::msg::Float32_<std::allocator<void > >, (__gnu_cxx::_Lock_policy)2u>::__shared_ptr(std::remove_referencestd::__shared_ptr<rclcpp::Publisher<std_msgs::msg::String_<std::allocator<void >, std::allocator >, (__gnu_cxx::_Lock_policy)2u>&>::type)’ __shared_ptr(std::move(__r)).swap(*this);


Originally posted by aks on ROS Answers with karma: 667 on 2018-05-16

Post score: 0


Original comments

Comment by gvdhoorn on 2018-05-17:
I'm going to say: yes.

Comment by aks on 2018-05-17:
ok...it gives me this error in this case : error: ambiguous overload for ‘operator=’ (operand types are ‘std_msgs::msg::String_<std::allocator<void> >::_data_type {aka std::__cxx11::basic_string<char>}’ and ‘int’) msg_->data = 0;}

Comment by gvdhoorn on 2018-05-17:
I'm confused by the mention of std_msgs::msg::String in the error message. Did you update the type of the msg_ member variable as well? You'll have to make sure to make these changes consistently, or things won't work.

Comment by aks on 2018-05-17:
sorry ! yes now i did...with another error message error: ‘Float32’ is not a member of ‘std_msgs::msg’ std::shared_ptr<std_msgs::msg::Float32> msg_; Do i need to declare some special header file ?

Comment by marguedas on 2018-05-17:
Each message generates its own set of headers. Replacing #include "std_msgs/msg/string.hpp" by #include "std_msgs/msg/float32.hpp" should do the job

Comment by aks on 2018-05-17:
@marguedas: yes this would be an alternative but for this then i need to create another msg definition and build it to use #include "std_msgs/msg/float32.hpp" What i meant was since, float32 also belongs to the std_msgs class, shouldnt it be directly possible ?

Comment by gvdhoorn on 2018-05-17:
No, you don't. std_msgs already contains a msg for Float32, so you can just reuse that.

What i meant was since, float32 also belongs to the std_msgs class, shouldnt it be directly possible ?

yes, but you need to include the header. How else is the compiler going to know what you are using?

Comment by marguedas on 2018-05-17:\

What i meant was since, float32 also belongs to the std_msgs class, shouldnt it be directly possible ?

Yes the Float32 message class is already provided by the std_msgs package. So you can use it without creating a new msg definition. To use it you need to include std_msgs/msg/float32.hpp

Comment by aks on 2018-05-17:
Thank you all for your suggestions. Implemented the same but still a shared pointer error. Edited the question with the complete code. @marguedas @gvdhoorn

Comment by aks on 2018-05-17:
I found the mistake : while creating the publisher, i used String instead of Float32 and thus it showed an error that there was no matching function. Also edited in the question. Thanks for the support.

Comment by marguedas on 2018-07-04:
@aakash_sehgal: can you please summarize the solution and post it as an answer so that this question can be marked as solved? Thanks!

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Yes, float32 messages could be used instead of string.

Just include the std_msgs/msg/float32.hpp and also keep in mind to update the type of the member variable msg_


Originally posted by aks with karma: 667 on 2018-07-04

This answer was ACCEPTED on the original site

Post score: 0

$\endgroup$

Your Answer

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