Stage机器人仿真实验(Ubuntu16.04+Kinetic)

参考https://www.jianshu.com/p/682e80efbe5a
首先创建工作空间,创建工作空间

mkdir -p ~/test_ws/src
cd  ~/test_ws
catkin_make 
source devel/setup.bash

在~t/test_ws/src下创建功能包,创建功能包

catkin_create_pkg beginner_tutorials std_msgs roscpp rospy

在~/test_ws/src/beginner_tutorials中拷贝从/opt/ros/kinetic/share/turtlebot_stage中复制的maps文件夹
在~/test_ws/src/beginner_tutorials/src中创建sharemem.h文件,其中定义共享空间中的数据结构。文件内容为

#ifndef SHAREMEM_H
#define SHAREMEM_H
struct ShareMem
{
  double x; //  x方向的速度(前后)
  double y; //  y方向的速度(左右)
  double z; //  旋转
};
#endif

新建talker节点。创建共享内存、监听共享内存区域的速度变化和发布速度话题。

/****************************************
*文件名: talker.cpp            *
*简介: 链接非ROS进程和ROS节点的ROS节点   *
*BY: CR (qq: 414481619)         *
*创建时间: 2018.10.09           *
****************************************/

#include "ros/ros.h"
#include <geometry_msgs/Twist.h>

#include <iostream>
#include <stdio.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pthread.h>

#include "sharemem.h"

using namespace std;


int main(int argc, char **argv)
{

  ros::init(argc, argv, "talker");
  ros::NodeHandle n;
  ros::Publisher chatter_pub = n.advertise<geometry_msgs::Twist>("cmd_vel", 1000);

  ros::Rate loop_rate(100); // 100Hz的定时器

  
  ShareMem _ShareMem;
  // 创建共享内存 ,相当于打开文件,文件不存在则创建
  int shmid = shmget((key_t)2333, sizeof(_ShareMem), 0666|IPC_CREAT);  
  if(shmid==-1)
  {
    perror("shmget err");
    return errno;
  }
  cout<<shmid<<endl; 

  // 将共享内存段连接到进程地址空间, 第二个参数shmaddr为NULL,核心自动选择一个地址
  ShareMem *shareMem = (ShareMem *)shmat(shmid, NULL, 0); 
  if (shareMem == (void *)-1 )
  {
    perror("shmat err");
    return errno;
  }
  
  shareMem->x = 0;  
  shareMem->y = 0; 
  shareMem->z = 0; 

  pthread_mutex_t mutex;  
  pthread_mutex_init(&mutex, NULL);
  while (ros::ok())
  {
    geometry_msgs::Twist cmdvel_msg; 

    pthread_mutex_lock(&mutex);
    cmdvel_msg.linear.x = shareMem->x;  
    cmdvel_msg.linear.y = shareMem->y; 
    cmdvel_msg.angular.z = shareMem->z; 
    pthread_mutex_unlock(&mutex);
    chatter_pub.publish(cmdvel_msg);

    ros::spinOnce();

    loop_rate.sleep();
  }
  pthread_mutex_destroy(&mutex);
  shmdt(shareMem);  //将共享内存段与当前进程脱离
  shmctl(shmid, IPC_RMID, NULL); //IPC_RMID为删除内存段
  return 0;
}

在beginner_tutorials 的 CMakeLists.txt 中添加:

include_directories(include ${catkin_INCLUDE_DIRS})

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

在终端中:

cd ~/test_ws
catkin_make

创建launch文件新建launch文件夹,创建stage_tast.launch文件。

<!--   
  stage_test 
  - stage_ros
  - talker
 -->
<launch>  
  <arg name="world_file"     default=" $(find beginner_tutorials)/maps/stage/maze.world"/>  

  <node pkg="stage_ros" type="stageros" name="stageros" args="$(arg world_file)">  
    <param name="base_watchdog_timeout" value="0.5"/>  
    <remap from="odom" to="odom"/>  
    <remap from="base_pose_ground_truth" to="base_pose_ground_truth"/>  
    <remap from="cmd_vel" to="cmd_vel"/>  
  </node>  

  <node pkg="beginner_tutorials" type="talker" name="talker">
  </node>  

</launch>  

创建速度控制父类,便于其他速度控制类的编写,其他速度控制类只需要继承父类的框架,完成自己的mainloop()就好。

/****************************************
*文件名: VelControl.h          *
*简介: 速度控制父类         *
*BY: CR (qq: 414481619)         *
*创建时间: 2018.10.09           *
****************************************/

// this code ism't in ros system 

#include <iostream>
#include <stdio.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#include "sharemem.h"

using namespace std;

class VelControl
{
public:
    VelControl();
    ~VelControl();
    void mainloop();
protected:
    ShareMem *shareMem;
    pthread_mutex_t mutex;  
    void writeVel(double x, double y, double z);
};

VelControl::VelControl()
{
    pthread_mutex_init(&mutex, NULL);

    // 绑定共享内存
    int shmid = shmget((key_t)2333, 0, 0);  
    if(shmid != -1)
    {
        shareMem =(ShareMem *)shmat(shmid, NULL, 0);
        cout<<shmid<<endl;
    }
    else
    {
        cout<<"ERROR: stage_test haven't started"<<endl;
        exit(1);
    }
}

VelControl::~VelControl()
{
    shmdt(shareMem);  //将共享内存段与当前进程脱离
    pthread_mutex_destroy(&mutex);
}


void VelControl::writeVel(double x, double y, double z)
{
    pthread_mutex_lock(&mutex);
    shareMem->x = x;  
    shareMem->y = y; 
    shareMem->z = z;
    pthread_mutex_unlock(&mutex);
}

键盘控制例程

/****************************************
*文件名: keyboard_not_ros.cpp      *
*简介: 速度控制例程         *
*BY: CR (qq: 414481619)         *
*创建时间: 2018.10.09           *
****************************************/

// this code isn't in ros system 

#include "VelControl.h"

using namespace std;

class keyboard_not_ros:VelControl
{
public:
    void mainloop();
};

void keyboard_not_ros::mainloop()
{
    char c = 'a';
    while(c!='q')
    {
        cout<<"please input a letter"<<endl;
        c = getchar();
        getchar();
        double x,y,z;
        switch(c)
        {
            
            case 'W':
            case 'w':
                x = 1;
                y = 0;
                z = 0;
                break;
            case 'S':
            case 's':
                x = -1;
                y = 0;
                z = 0;
                break;
            case 'A':
            case 'a':
                x = 0;
                y = 0;
                z = 1;
                break;
            case 'D':
            case 'd':
                x = 0;
                y = 0;
                z = -1;
                break;
            default:;
        }
        writeVel(x, y, z);
        usleep(100*1000);
        writeVel(0,0,0);
    }
}


int main(int argc, char const *argv[])
{
    keyboard_not_ros k;
    k.mainloop();
    return 0;
}

编译程序,在 ~/test_ws/src/beginner_tutorials/src/ 目录下,终端输入:
g++ -o keyboard_not_ros keyboard_not_ros.cpp
启动launch文件

roslaunch beginner_tutorials stage_test.launch 

另一个终端中,~/test_ws/src/beginner_tutorials/src下输入

./keyboard_not_ros
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容