使用C++向Rviz发送简单的形状

在这里插入图片描述
按照RVIZ的官方教材来一步步来,Markers: Sending Basic Shapes (C++),第一步先学习如何使用visualization_msgs/Marker 类型的消息发送简单的形状给RVIZ。
在~/rviz_ws/src中运行

catkin_create_pkg using_markers roscpp visualization_msgs
gedit using_markers/src/basic_shapes.cpp

cpp的代码如下:

#include <ros/ros.h>
#include <visualization_msgs/Marker.h>

int main( int argc, char** argv )
{
  ros::init(argc, argv, "basic_shapes");
  ros::NodeHandle n;
  ros::Rate r(1);
  ros::Publisher marker_pub = n.advertise<visualization_msgs::Marker>("visualization_marker", 1);

  // Set our initial shape type to be a cube
  uint32_t shape = visualization_msgs::Marker::CUBE;

  while (ros::ok())
  {
    visualization_msgs::Marker marker;
    // Set the frame ID and timestamp.  See the TF tutorials for information on these.
    marker.header.frame_id = "/my_frame";
    marker.header.stamp = ros::Time::now();

    // Set the namespace and id for this marker.  This serves to create a unique ID
    // Any marker sent with the same namespace and id will overwrite the old one
    marker.ns = "basic_shapes";
    marker.id = 0;

    // Set the marker type.  Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
    marker.type = shape;

    // Set the marker action.  Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
    marker.action = visualization_msgs::Marker::ADD;

    // Set the pose of the marker.  This is a full 6DOF pose relative to the frame/time specified in the header
    marker.pose.position.x = 0;
    marker.pose.position.y = 0;
    marker.pose.position.z = 0;
    marker.pose.orientation.x = 0.0;
    marker.pose.orientation.y = 0.0;
    marker.pose.orientation.z = 0.0;
    marker.pose.orientation.w = 1.0;

    // Set the scale of the marker -- 1x1x1 here means 1m on a side
    marker.scale.x = 1.0;
    marker.scale.y = 1.0;
    marker.scale.z = 1.0;

    // Set the color -- be sure to set alpha to something non-zero!
    marker.color.r = 0.0f;
    marker.color.g = 1.0f;
    marker.color.b = 0.0f;
    marker.color.a = 1.0;

    marker.lifetime = ros::Duration();

    // Publish the marker
    while (marker_pub.getNumSubscribers() < 1)
    {
      if (!ros::ok())
      {
        return 0;
      }
      ROS_WARN_ONCE("Please create a subscriber to the marker");
      sleep(1);
    }
    marker_pub.publish(marker);

    // Cycle between different shapes
    switch (shape)
    {
    case visualization_msgs::Marker::CUBE:
      shape = visualization_msgs::Marker::SPHERE;
      break;
    case visualization_msgs::Marker::SPHERE:
      shape = visualization_msgs::Marker::ARROW;
      break;
    case visualization_msgs::Marker::ARROW:
      shape = visualization_msgs::Marker::CYLINDER;
      break;
    case visualization_msgs::Marker::CYLINDER:
      shape = visualization_msgs::Marker::CUBE;
      break;
    }

    r.sleep();
  }
}

头文件不解释了

  ros::init(argc, argv, "basic_shapes");
  ros::NodeHandle n;
  ros::Rate r(1);
  ros::Publisher marker_pub = n.advertise<visualization_msgs::Marker>("visualization_marker", 1);

这四句话可以参考ROS教程中创建一个消息发布器的内容理解。
先初始化ROS。之后为这个进程的节点创建一个句柄。第一个创建的NodeHandle会为节点进行初始化,最后一个销毁的NodeHandle则会释放该节点所占用的所有资源。
定义循环频率。它会追踪记录自上一次调用Rate::sleep()后时间的流逝,并休眠直到一个频率周期的时间。
告诉 master 我们将要在visualization_marker(话题名) 上发布visualization_msgs::Marker消息类型的消息。这样 master 就会告诉所有订阅了visualization_marker话题的节点,将要有数据发布。第二个参数是发布序列的大小。如果我们发布的消息的频率太高,缓冲区中的消息在大于 1个的时候就会开始丢弃先前发布的消息。

uint32_t shape = visualization_msgs::Marker::CUBE;

定义一个变量shape表示我们Marker的类型。

visualization_msgs::Marker marker;
// Set the frame ID and timestamp.  See the TF tutorials for information on these.
marker.header.frame_id = "/my_frame";
marker.header.stamp = ros::Time::now();

其实这里我没有太明白。要设置frame的ID和时间戳。教程说让我去看tf的教程,好的,下次一定。
程序其他没有什么太难理解的地方。
之后就是修改CmakeLists.txt,在最后加上两句话生成可执行文件

add_executable(basic_shapes src/basic_shapes.cpp)
target_link_libraries(basic_shapes ${catkin_LIBRARIES})

准备运行\

cd ~/rviz_ws
catkin_make
roscore
rosrun using_markers basic_shapes

接下来启动RVIZ

rosrun rviz rviz

修改Fixed Frame
在这里插入图片描述

接下来添加一个Marker
在这里插入图片描述
之后就能看到我们想要的结果了。
在这里插入图片描述在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
使用 C++ 发送 UDP 组播信息需要完成以下步骤: 1. 创建 UDP 套接字并设置相关参数,如 IP 地址、端口号等。 ```c++ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int sockfd; struct sockaddr_in addr; sockfd = socket(AF_INET, SOCK_DGRAM, 0); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("组播地址"); addr.sin_port = htons(端口号); int loop = 1; setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)); ``` 2. 绑定套接字到本地 IP 地址和端口号。 ```c++ struct sockaddr_in local_addr; memset(&local_addr, 0, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = inet_addr("本地地址"); local_addr.sin_port = htons(端口号); bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); ``` 3. 发送 UDP 数据包。 ```c++ char buffer[1024]; strcpy(buffer, "Hello, multicast!"); sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)&addr, sizeof(addr)); ``` 完整代码如下: ```c++ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> int main() { int sockfd; struct sockaddr_in addr; sockfd = socket(AF_INET, SOCK_DGRAM, 0); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("组播地址"); addr.sin_port = htons(端口号); int loop = 1; setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)); struct sockaddr_in local_addr; memset(&local_addr, 0, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = inet_addr("本地地址"); local_addr.sin_port = htons(端口号); bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); char buffer[1024]; strcpy(buffer, "Hello, multicast!"); sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)&addr, sizeof(addr)); close(sockfd); return 0; } ``` 需要注意的是,在发送组播数据时,需要设置 `IP_MULTICAST_LOOP` 选项为 1,否则发送的数据会被回送到本地。同时,需要使用 `sendto` 函数发送数据包,并指定目标地址和端口号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yhwang-hub

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值