二自由度机械臂的gazebo仿真

news2024/12/24 9:55:02

一、创建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>

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科研经费的来源有哪些?

目前&#xff0c;高校在我国科技创新中发挥着越来越重要的作用&#xff0c;自然高校获得经费也越来越多。一所高校的科研经费充足&#xff0c;越有利于科研学术水平的提高。那么科研经费的来源有哪些呢&#xff1f; 1. 国家拨款 对于高校的科研发展享有国家的重点支持。近年来…

人工智能原理(3)

目录 一、搜索策略 1、引言 2、盲目搜索 3、启发式搜索 二、基于状态空间图搜索技术 1、图搜索基本概念 2、状态空间搜索 3、一般的图搜索算法 三、盲目搜索 1、广度优先搜索 2、深度优先搜索 3、有界深度搜索和迭代加深搜索 四、启发式算法 1、启发性信息和评估…

容器技术发展和编排技术演进之路

目录 Jail 时代 1979 年 贝尔实验室发明 chroot 2000 年 FreeBSD 4.0 发行 FreeBSD Jail 2001 年 Linux VServer 发行 2004 年 Solaris Containers 发行 云时代 2006 年 google 推出 Process Containers 2008 年 LXC 推出 2011 年 CloudFoundry 推出 Warden 2013 年 LMCTFY 启动…

JavaScript 【DOM】

【DOM】 原创内容&#xff0c;转载请注明出处&#xff01; 一、DOM基本概念 DOM&#xff08;Document Object Model&#xff0c;文档对象模型&#xff09;是 JavaScript 操作 HTML 文档的接口&#xff0c;使文档操作变得非常优雅、简便。 DOM 最大的特点就是将 HTML 文档表示…

Pycharm找不到Conda可执行文件路径(Pycharm无法导入Anaconda已有环境)

在使用Pycharm时发现无法导入Anaconda创建好的环境&#xff0c;会出现找不到Conda可执行文件路径的问题。 解决 在输入框内输入D:\anaconda3\Scripts\conda.exe&#xff0c;点击加载环境。 注意前面目录是自己Anaconda的安装位置&#xff0c;之后就可以找到Anaconda的现有环…

STM32F407使用Helix库软解MP3并通过DAC输出,最精简的STM32+SD卡实现MP3播放器

只用STM32单片机SD卡耳机插座&#xff0c;实现播放MP3播放器&#xff01; 看过很多STM32软解MP3的方案&#xff0c;即不通过类似VS1053之类的解码器芯片&#xff0c;直接用STM32和软件库解码MP3文件&#xff0c;通常使用了labmad或者Helix解码库实现&#xff0c;Helix相对labm…

Mariadb高可用MHA

本节主要学习了Mariadb高可用MHA的概述&#xff0c;案例如何构建MHA 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、概述 1、概念 MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。…

如何使用Kali Linux进行渗透测试?

1. 渗透测试简介 渗透测试是通过模拟恶意攻击&#xff0c;评估系统、应用或网络的安全性的过程。Kali Linux为渗透测试人员提供了丰富的工具和资源&#xff0c;用于发现漏洞、弱点和安全风险。 2. 使用Kali Linux进行渗透测试的步骤 以下是使用Kali Linux进行渗透测试的基本…

搭建WebDAV服务手机ES文件浏览器远程访问

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址6. 使用固定地址测试连接 有时候我们想通过移动设备访问群晖NAS 中的文件,以满足特殊需求,我们在群辉中开启WebDav服务,结合cpolar内网工具生成的公网地址,通过移动客户端ES文件…

【Unity每日一记】进行发射,位置相关的方法总结

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

绘制世界地图or中国地图

写在前面 在8月初,自己需要使用中国地图的图形,自己就此也查询相关的教程,自己也做一下小小总结,希望对自己和同学们有所帮助。 最终图形 这个系列从2022年开始,一直更新使用R语言分析数据及绘制精美图形。小杜的生信笔记主要分享小杜学习日常!如果,你对此感兴趣可以加…

【C++面向对象】--- 继承 的奥秘(下篇)

个人主页&#xff1a;平行线也会相交&#x1f4aa; 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】&#x1f48c; 本专栏旨在记录C的学习路线&#xff0c;望对大家有所帮助&#x1f647;‍ 希望我们一起努力、成长&…

自动化测试用例设计实例

在编写用例之间&#xff0c;笔者再次强调几点编写自动化测试用例的原则&#xff1a; 1、一个脚本是一个完整的场景&#xff0c;从用户登陆操作到用户退出系统关闭浏览器。 2、一个脚本脚本只验证一个功能点&#xff0c;不要试图用户登陆系统后把所有的功能都进行验证再退出系统…

CAS 的执行流程 ?CAS 中 ABA 问题如何解决 ?CAS 在 Java 中有哪些实现类 ?

目录 1. CAS 的执行流程 2. CAS 中的 ABA 问题 3. 如何解决 CAS 中的 ABA 问题 4.CAS 在Java 中的实现类有哪些 1. CAS 的执行流程 CAS 比较并替换的大致流程是这样的&#xff1a; 它有三个操作单位&#xff1a;V&#xff08;内存值&#xff09;&#xff0c;A&#xff08;…

【C++】做一个飞机空战小游戏(八)——生成敌方炮弹(rand()和srand()函数应用)

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…

Iceberg 学习笔记

本博客对应于 B 站尚硅谷教学视频 尚硅谷数据湖Iceberg实战教程&#xff08;尚硅谷&Apache Iceberg官方联合推出&#xff09;&#xff0c;为视频对应笔记的相关整理。 1. Iceberg简介 1.1 概述 为了解决数据存储和计算引擎之间的适配的问题&#xff0c;Netflix 开发了 I…

【算法题】螺旋矩阵IV (求解n阶折线蛇形矩阵)

一、问题的提出 n阶折线蛇形矩阵的特点是按照图1所示的方式排列元素。n阶蛇形矩阵是指矩阵的大小为nn&#xff0c;其中n为正整数。 题目背景 一个 n 行 n 列的螺旋矩阵可由如图1所示的方法生成&#xff0c;观察图片&#xff0c;找出填数规律。填数规则为从 1 开始填到 nn。 …

如何使用AIGC人工智能辅助开发?

文章目录 引言AIGC辅助开发的应用场景代码生成图像识别与生成自然语言处理视频剪辑与生成 AIGC辅助开发的实现步骤数据准备模型选择模型训练结果评估与优化应用开发 AIGC辅助开发的优势与局限优势局限 未来展望总结 &#x1f389;欢迎来到AIGC人工智能专栏~如何使用AIGC人工智能…

计算机网络----CRC冗余码的运算

目录 1. 冗余码的介绍及原理2. CRC检验编码的例子3. 小练习 1. 冗余码的介绍及原理 冗余码是用于在数据链路层的通信链路和传输数据过程中可能会出错的一种检错编码方法&#xff08;检错码&#xff09;。原理&#xff1a;发送发把数据划分为组&#xff0c;设每组K个比特&#…

【Python】解决“Tk_GetPixmap: Error from CreateDIBSection”闪退问题

解决Python使用Tkinter的Notebook切换标签时出现的“Tk_GetPixmap: Error from CreateDIBSection 操作成功完成”闪退问题 零、问题描述 在使用Tkinter的Notebook控件时&#xff0c;对其标签进行切换&#xff0c;发现切换不了&#xff0c;一切换就报如下图错误&#xff1a; …