二自由度机械臂的gazebo仿真

一、创建ros软件包

#1、创建工作空间
mkdir 2d_robot_ws
cd 2d_robot_ws
mkdir src
cd src
catkin_init_workspace
#2、编译工作空间
cd ..
catkin_make
#3、创建软件包
catkin_create_pkg 2d_robot std_msgs rospy roscpp

二、创建模型文件

1、编写urdf模型文件

在2d_robot_ws/src/2d_robot下创建launch文件夹和urdf文件夹,launch文件夹中放启动文件,urdf文件夹中放模型文件。

2d_robot_model.urdf

<?xml version="1.0"?>
<robot name="my_robot">

    <link name="link_base">            基座机构
        <inertial>
            <origin  xyz="0 0 0" rpy="0 0 0"/>
            <mass value="10"/>
            <inertia ixx="100" ixy="0" ixz="0" iyy="100" izz="100" iyz="0"/>
        </inertial>
        
        <visual>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>    
            <geometry>
                <box size="5.0 5.0 1.0"/>
            </geometry>
            <material name="123">
                <color rgba="0.0 1.0 1.0 1.0"/>
            </material>
        </visual>

        <collision>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
            <geometry>
                <box size="5.0 5.0 1.0"/>
            </geometry>
        </collision>

    </link>


   <link name="link_one">         第二个机构
        <inertial>
            <origin  xyz="0.0 0.0 5.0" rpy="0.0 0.0 0.0"/>
            <mass value="5"/>
            <inertia ixx="100" ixy="0" ixz="0" iyy="100" izz="100" iyz="0"/>
        </inertial>
        
        <visual>
            <origin xyz="0.0 0.0 5.0" rpy="0.0 0.0 0.0"/>    
            <geometry>
                <box size="3.0 3.0 10.0"/>
            </geometry>
            <material name="234">
                <color rgba="0.8 0.5 0 0.5"/>
            </material>
        </visual>

        <collision>
            <origin xyz="0.0 0.0 5.0" rpy="0.0 0.0 0.0"/>
            <geometry>
                <box size="1.0 1.0 10.0"/>
            </geometry>
        </collision>
        
    </link>


   <link name="link_two">            第二个机构
        <inertial>
            <origin  xyz="0.0 0.0 5.0" rpy="0.0 0.0 0.0"/>
            <mass value="5"/>
            <inertia ixx="100" ixy="0" ixz="0" iyy="100" izz="100" iyz="0"/>
        </inertial>
        
        <visual>
            <origin xyz="0.0 0.0 5.0" rpy="0.0 0.0 0.0"/>    
            <geometry>
                <box size="1.0 1.0 10.0"/>
            </geometry>
            <material name="234">
                <color rgba="0.0 5.0 1.0 1.0"/>
            </material>
        </visual>

        <collision>
            <origin xyz="0.0 0.0 5.0" rpy="0.0 0.0 0.0"/>
            <geometry>
                <box size="1.0 1.0 10.0"/>
            </geometry>
        </collision>
        
    </link>


    <joint name="joint_one" type="revolute">           第一个关节,连接基座和机构1
        <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
        <parent link="link_base"/>
        <child link="link_one"/>
        <axis xyz="1.0 0.0 0.0"/>
        <limit lower="-3.0" upper="3.0" effort="10.0" velocity="3.0"/>
    </joint>


    <joint name="joint_two" type="revolute">            第二个关节,连接机构1和机构2
        <origin xyz="0.0 0.0 10.0" rpy="0.0 0.0 0.0"/>
        <parent link="link_one"/>
        <child link="link_two"/>
        <axis xyz="1.0 0.0 0.0"/>
        <limit lower="-3.0" upper="3.0" effort="10.0" velocity="3.0"/>
    </joint>

</robot>

2、用rviz查看urdf模型

2d_robot_rviz.launch

<?xml version="1.0"?>
<launch>
    <arg name="model" />
    <!-- 加载机器人模型参数 -->
    <param name="robot_description" textfile="/media/wangyuanhao/DATA/ros_data/2d_robot_ws/src/2d_robot/urdf/2d_robot_model.urdf" />
 
    <!-- 设置GUI参数,显示关节控制插件 -->
    <param name="use_gui" value="true"/>
 
    <!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
    
    <!-- 运行robot_state_publisher节点,发布tf  -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
 
    <!-- 运行rviz可视化界面 -->
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" />
</launch>

roslaunch命令

roslaunch 2d_robot 2d_robot_rviz.launch

启动rviz后添加机器人类型,并设置fixed frame
在这里插入图片描述

3、urdf转sdf

gz sdf -p 2d_robot_model.urdf > 2d_robot_model.sdf

三、gazebo仿真

1、编写模型文件

要让sdf模型文件可以在world文件中引用需要sdf和config两个文件,新建一个文件夹命名为2d_robot,其中分别有model.sdf和model.config文件。
model.sdf就是一般的sdf文件,config文件如下:
model.config

<?xml version="1.0"?>
<model>
  <name>My Robot</name>
  <version>1.0</version>
  <sdf version='1.4'>model.sdf</sdf>

  <author>
   <name>My Name</name>
   <email>me@my.email</email>
  </author>

  <description>
    My awesome robot.
  </description>
</model>

2、编写world文件(导入sdf模型)

2d_robot.world

<?xml version="1.0" ?>
<sdf version="1.4">
  <world name="default">
    <include>
      <uri>model://ground_plane</uri>
    </include>
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <scale>1 1 1</scale>      
      <uri>///media/wangyuanhao/DATA/ros_data/2d_robot_ws/src/2d_robot/sdf/2d_robot</uri>
      <name>2d_robot</name>
      <pose>-2.0 7.0 0 0 0 0</pose>
    </include>
  </world>
</sdf>

2、将world文件导入gazebo(空白世界+world文件)

2d_robot_gazebo.launch

<launch>
  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(find 2d_robot)/worlds/2d_robot.world"/>
    <!-- more default parameters can be changed here -->
  </include>
</launch>

roslaunch启动命令

roslaunch 2d_robot 2d_robot_gazebo.launch

在这里插入图片描述

3、world文件中加入gazebo插件

3.1添加世界插件hello_world

3.1.1编写插件

hello_world.cc

#include <gazebo/gazebo.hh>

namespace gazebo
{
  class WorldPluginTutorial : public WorldPlugin
  {
    public: WorldPluginTutorial() : WorldPlugin()
            {
              printf("Hello World!\n");
            }

    public: void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
            {
            }
  };
  GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
}

3.1.2编译插件

CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

find_package(gazebo REQUIRED)
include_directories(${GAZEBO_INCLUDE_DIRS})
link_directories(${GAZEBO_LIBRARY_DIRS})
list(APPEND CMAKE_CXX_FLAGS "${GAZEBO_CXX_FLAGS}")

add_library(hello_world SHARED hello_world.cc)
target_link_libraries(hello_world ${GAZEBO_LIBRARIES})

在这里插入图片描述这里要注意一下不能使用boost1.69以上的库,所以要确认自己的版本。

添加so文件路径
我这里是把so文件放到了gazebo的插件路经的文件夹中,我电脑的路径是/usr/lib/x86_64-linux-gnu/gazebo-9/plugins。

3.1.3在world中引用

2d_robot.world

<?xml version="1.0" ?>
<sdf version="1.4">
  <world name="default">
  <plugin name="hello_world" filename="libhello_world.so"/>
    <include>
      <uri>model://ground_plane</uri>
    </include>
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <scale>1 1 1</scale>      
      <uri>///media/wangyuanhao/DATA/ros_data/2d_robot_ws/src/2d_robot/sdf/2d_robot</uri>
      <name>2d_robot</name>
      <pose>-2.0 7.0 0 0 0 0</pose>
    </include>
  </world>
</sdf>

最终效果:
在这里插入图片描述

3.2添加模型插件pos_update

https://blog.csdn.net/Robot_Starscream/article/details/120323907
https://zhuanlan.zhihu.com/p/363385163

3.2.1编写插件

这里主要就是借鉴了第一个链接里面的代码,只是可能因为版本不同,get_angle的函数没有了换成了GetForce。
back_wheel_steering.hh

#ifndef _BACK_WHEEL_ROLLINGANGLE_HH_
#define _BACK_WHEEL_ROLLINGANGLE_HH_
 
#include <boost/thread.hpp>
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
#include <thread>
 
// gazebo
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
 
#include <gazebo/gazebo_client.hh>
#include <gazebo/msgs/msgs.hh>
#include <gazebo/transport/transport.hh>
 
#include "std_msgs/Float64.h"
#include "ros/callback_queue.h"
#include "ros/ros.h"
#include "ros/subscribe_options.h"
#include "ros/subscription_callback_helper.h"
 
namespace gazebo{
	class back_wheel_steering : public ModelPlugin{
        public:
                virtual ~back_wheel_steering();
                back_wheel_steering();
                void virtual Load(physics::ModelPtr _model, sdf::ElementPtr _sdf);
                void OnUpdate();
                double B_wheel_steering;
 
        private:
                physics::ModelPtr model;
                physics::JointPtr prismaticJoint;
                event::ConnectionPtr BWP_updateConnection;
                ros::NodeHandle P_joint_steering_Node;
                ros::Publisher rosPub_P_joint_steering;
                std::string P_joint_steering_PubTopic;
                std_msgs::Float64 B_wheel_steering_msg;
 
                int SimulateCount=0;
                int PrintStep=1000;
    };
        
}
#endif

back_wheel_steering.cc

#include "back_wheel_steering.hh"
#define IS_DEBUG 0
namespace gazebo
{
    back_wheel_steering::back_wheel_steering(){
        std::cout << "start1" << std::endl;
        std::cout << "start2" << std::endl;
    }
    back_wheel_steering::~back_wheel_steering(){}
     
    void back_wheel_steering::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf){
        // Just output a message for now 
        //std::cerr << "\nThe velodyne plugin is attach to model[" << _model->GetName() << "]\n";
        std::cout << "go in Load" << std::endl; 
        this->model = _model;
        this->prismaticJoint = this->model->GetJoint(_sdf->GetElement("prismaticJoint")->Get<std::string>());   //_sdf是插件标签的指针,等于说获取了插件的参数
        this->P_joint_steering_PubTopic = _sdf->GetElement("P_joint_position_Topic")->Get<std::string>();
 
        rosPub_P_joint_steering = this->P_joint_steering_Node.advertise<std_msgs::Float64>(P_joint_steering_PubTopic, 10);
        this->BWP_updateConnection = event::Events::ConnectWorldUpdateBegin(
            std::bind(&back_wheel_steering::OnUpdate, this));
    }
 
    void back_wheel_steering::OnUpdate(){
        B_wheel_steering = this->prismaticJoint->GetForce(0);
        B_wheel_steering_msg.data = B_wheel_steering;
        rosPub_P_joint_steering.publish(B_wheel_steering_msg);
        SimulateCount++;
    //    std::cout << "++++++++++++++++++++++++++++++++" << std::endl;
        if ((SimulateCount % PrintStep == 0)){
            std::cout << "++++++++++++++++++++++++++++++++" << std::endl;
            std::cout<< "back_wheel_steeringangle:" << B_wheel_steering<<std::endl;
            std::cout << "++++++++++++++++++++++++++++++++" << std::endl;
        }
    }
    
GZ_REGISTER_MODEL_PLUGIN(back_wheel_steering)
}

3.2.2编译插件

因为代码中使用了ros的msg,所以引入了ros的一些依赖。
CMakeLists.txt

cmake_minimum_required(VERSION 3.0.2)
project(gazebo_joint_plug_pkg)
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
)
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)
find_package(gazebo REQUIRED)
include_directories(${GAZEBO_INCLUDE_DIRS})
link_directories(${GAZEBO_LIBRARY_DIRS})
list(APPEND CMAKE_CXX_FLAGS "${GAZEBO_CXX_FLAGS}")

add_library(joint_plug SHARED src/back_wheel_steering.cc)
target_link_libraries(joint_plug ${GAZEBO_LIBRARIES})

3.2.3在world中引用

注意这部分代码要插入到sdf模型文件中,joint_two是关节名,要和sdf文件中的一样。

    <plugin name="joint_two_control" filename="libjoint_two_control.so">  
	<prismaticJoint>joint_two</prismaticJoint>    
	<P_joint_position_Topic>/joint_two_pos</P_joint_position_Topic>
    </plugin>

最终效果:
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/75501.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLMs大模型plugin开发实战

一、概述 ChatGPT是通用语言大模型&#xff0c;如果用户想要在与大模型进行交互时能够使用到企业私有的数据&#xff0c;那么可以通过开发plugin&#xff08;插件&#xff09;的方式来实现&#xff0c;另外GPT3.5模型的训练数据是截止到2021年9月&#xff0c;如果想让模型能够…

mysql-5.5.62-win32安装与使用

1.为啥是这个版本而不是当前最新的8.0&#xff1f; 因为我要用32位。目前mysql支持win32的版本最新只到5.7.33。 首先&#xff0c;到官网MySQL :: MySQL Downloads 然后选 选一个自己喜欢的版本就好。我这里是如标题版本。下载32位的zip。然后回来解压。 完了创建系统环境变…

29 深度玻尔兹曼机

文章目录 29 深度玻尔兹曼机29.1 背景介绍29.2 DBM的叠加方式 29 深度玻尔兹曼机 29.1 背景介绍 过去在解决BM问题的时候&#xff0c;提出过多种模型&#xff1a;RBM、SBN、DBN 其中RBM是一种有限制条件的&#xff0c;简化的BM&#xff0c;限制了隐藏层和观测层内部都没有连…

【数据结构OJ题】移除链表元素

原题链接&#xff1a;https://leetcode.cn/problems/remove-linked-list-elements/description/ 1. 题目描述 2. 思路分析 我们可以定义一个结构体指针变量cur&#xff0c;让cur一开始指向头结点&#xff0c;同时定义一个结构体指针prev&#xff0c;令prev初始化为空指针NULL…

uniapp封装组件,选中后右上角显示对号√样式(通过css实现)

效果&#xff1a; 一、组件封装 1、在项目根目录下创建components文件夹&#xff0c;自定义组件名称&#xff0c;我定义的是xc-button 2、封装组件代码 <template><view class"handle-btn"><view :class"handleIdCode 1 ? select : unSelec…

Java多线程编程中的线程死锁

Java多线程编程中的线程死锁 ​ 在多线程编程中&#xff0c;线程死锁是一种常见的问题&#xff0c;它发生在两个或多个线程互相等待对方释放资源的情况下&#xff0c;导致程序无法继续执行。本文将介绍线程死锁的概念、产生原因、示例以及如何预防和解决线程死锁问题。 线程死…

less学习语法

1.CSS函数的补充 1.rgb/rgba/translate/rotate/scale 2.非常好用的css函数&#xff1a; var:使用css定义的变量calc:计算css值&#xff0c;通常用于计算元素的大小或位置blur:毛玻璃&#xff08;高斯模糊&#xff09;效果gradient:颜色渐变函数 var:定义变量 css中可以自定…

【Vue3】自动引入插件-`unplugin-auto-import`

Vue3自动引入插件-unplugin-auto-import&#xff0c;不必再手动 import 。 自动导入 api 按需为 Vite, Webpack, Rspack, Rollup 和 esbuild 。支持TypeScript。由unplugin驱动。 插件安装&#xff1a;unplugin-auto-import 配置vite.config.ts&#xff08;配置完后需要重启…

Verdi_traceX and autotrace

Verdi_traceX and autotrace Trace X From nWave/nTrace of from the Teporal Flow View. Show Paths on Flow ViewShow Paths on nWave 若Waveform中有X态&#xff0c;鼠标右键会有Trace X的选项&#xff1b; 会自动打开Temporal Flow View窗口&#xff0c;展示对应路径&am…

LangChain手记 Question Answer 问答系统

整理并翻译自DeepLearning.AILangChain的官方课程&#xff1a;Question Answer&#xff08;源代码可见&#xff09; 本节介绍使用LangChian构建文档上的问答系统&#xff0c;可以实现给定一个PDF文档&#xff0c;询问关于文档上出现过的某个信息点&#xff0c;LLM可以给出关于该…

docker打包运行中的容器,生成镜像文件保存到本地

因为想着方便部署&#xff0c;将所有没问题的项目容器打包成镜像&#xff0c;走到哪儿都离线安装自动部署。 第一步先把运行中的容器打包成镜像 docker commit 运行中容器id 像打包成的镜像名称第二步将大象装进冰箱&#xff0c;不好意思说错了&#xff0c;把镜像保存到本地 …

Hlang社区-社区导航栏实现

文章目录 前言项目结构导航实现创作中心移动小球消息提示完整代码前言 okey,这里的话是我们社区导航栏的实现: 废话不多说,看看效果: 我甚至为此用New Bing生成了一个Logo。 项目结构 废话不多说,先来看到我们的项目结构: 在这里导航栏是一个组件。 在App.vue里面直…

el-table分页后序号连续的两种方法

实现效果&#xff1a; 第一页排序到10&#xff0c;第二页的排序应从11开始 实现方法一&#xff1a; 在el-table的序号列中使用template定义 <el-table><el-table-columnmin-width"10%"label"序号"><template slot-scope"scope"…

htmlCSS-----弹性布局案例展示

目录 前言 效果展示 ​编辑 代码 思路分析 前言 上一期我们学习了弹性布局&#xff0c;那么这一期我们用弹性布局来写一个小案例&#xff0c;下面看代码&#xff08;上一期链接html&CSS-----弹性布局_灰勒塔德的博客-CSDN博客&#xff09; 效果展示 代码 html代码&am…

服务器遭受攻击之后的常见思路

哈喽大家好&#xff0c;我是咸鱼 不知道大家有没有看过这么一部电影&#xff1a; 这部电影讲述了男主是一个电脑极客&#xff0c;在计算机方面有着不可思议的天赋&#xff0c;男主所在的黑客组织凭借着超高的黑客技术去入侵各种国家机构的系统&#xff0c;并引起了德国秘密警察…

MyBatis的XML映射文件

Mybatis的开发有两种方式&#xff1a; 注解 XML配置文件 通过XML配置文件的形式来配置SQL语句&#xff0c;这份儿XML配置文件在MyBatis当中也称为XML映射文件。 导学&#xff1a;在MyBatis当中如何来定义一份儿XML映射文件&#xff1f; 在MyBatis当中&#xff0c;定义XML…

ROS学习笔记(三)---好用的终端Terminator

ROS学习笔记文章目录 01. ROS学习笔记(一)—Linux安装VScode 02. ROS学习笔记(二)—使用 VScode 开发 ROS 的Python程序&#xff08;简例&#xff09; 一、Terminator是什么&#xff1f; 在前面的学习中&#xff0c;为了运行hello.py我是在vscode频繁的点击运行窗口的“”号…

JS垃圾回收机制

什么是垃圾回收机制&#xff1f; 垃圾回收机制 (Garbage Collection) 简称GC JS中内存的分配和回收都是自动完成的&#xff0c;内存在不使用的时候会被垃圾回收器自动回收。 正因为垃圾回收器的存在&#xff0c;许多人认为JS不用太关心内存管理的问题 但如果不了解JS的内存管…

Mybatis 源码 ④ :TypeHandler

文章目录 一、前言二、DefaultParameterHandler1. DefaultParameterHandler#setParameters1.1 UnknownTypeHandler1.2 自定义 TypeHandler 三、DefaultResultSetHandler1. hasNestedResultMaps2. handleRowValuesForNestedResultMap2.1 resolveDiscriminatedResultMap2.2 creat…

【C++】C++入门基础详解(1)

本篇内容要分享的是C的基础内容&#xff0c;C的诞生简单的说就是为了填补C语言中的语法坑&#xff0c;同时对比C语言来说增添很多便捷的语法规则&#xff0c;使用起来比C语言便捷不少&#xff0c;但是学习难度也大大增强&#xff0c;不过难度是成线性增长&#xff0c;可以一步一…