Can i use Float32 messages with the talker example in ROS2 ?
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 ...
I'm going to say: yes.
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;}
I'm confused by the mention of
std_msgs::msg::String
in the error message. Did you update the type of themsg_
member variable as well? You'll have to make sure to make these changes consistently, or things won't work.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 ?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@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 ?No, you don't.
std_msgs
already contains a msg forFloat32
, so you can just reuse that.yes, but you need to include the header. How else is the compiler going to know what you are using?
Yes the
Float32
message class is already provided by thestd_msgs
package. So you can use it without creating a new msg definition. To use it you need to includestd_msgs/msg/float32.hpp