ROS

2023-05-16

ROS

1. ROS测试

启动ros master 打开一个终端roscore

启动小海龟仿真器 新打开一个终端rosrun turtlesim turtlesim_node

启动海龟控制节点 新打开一个终端rosrun turtlesim turtle_teleop_key

2. ROS是什么

一套为机器人所做的操作系统=通信机制+开发工具+应用功能+生态系统

通信机制:松耦合分布式通信

开发工具:命令行、TF坐标变换、Rviz、Qt工具箱、Gazebo

应用功能:Navigation、SLAM、Moveit

生态系统:发行版、软件源、ROS wiki、邮件列表、ROS Answers、博客

3. Ros中的核心概念

节点(Node)——执行单元

  • 执行具体任务的进程、独立运行的可执行文件
  • 不同节点可使用不同的编程语言,可分布式运行在不同的主机
  • 节点在系统中的名称必须是唯一的

节点管理器(ROS Master)——控制中心

  • 为节点提供命名和注册服务
  • 跟踪和记录话题/服务通信,辅助节点相互查找、建立连接
  • 提供参数服务器,节点使用此服务器存储和检索运行时的参数

话题(Topic)——异步通信机制

  • 节点间用来传输数据的重要总线
  • 使用发布/订阅模型,数据由发布者传输到订阅者,同一个话题的订阅者或发布者可以不唯一

消息(Message)——话题数据

  • 具有一定的类型和数据结构,包括ROS提供的标准类型和用户自定义类型
  • 使用编程语言无关的.msg文件定义,编译过程中生成对应的代码文件

服务(Service)——同步通信机制

  • 使用客户端/服务器(C./S)模型,可无端发送请求数据,服务器完成处理后返回应答数据
  • 使用编程语言无关的.srv文件定义请求和应答数据结构,编译过程中生成对应的代码文件
话题服务
同步性异步同步
通信模型发布/订阅服务端/客户端
底层协议ROSTCP/ROSUDPROSTCP/ROSUDP
反馈机制
缓冲区
实时性
节点关系多对多一对多
适用场景数据传输逻辑处理

参数(Parameter)——全局共享字典

  • 可通过网络访问的共享、多变量字典
  • 节点使用此服务器来存储和检索运行时的参数
  • 适合存储静态、非二进制的配置参数,不适合存储动态配置的数据

功能包(Package)

  • ROS软件中的基本单元,包含节点源码、配置文件、数据定义等

功能包清单(Package manifest)

  • 记录功能包的基本信息,包含作者信息、许可信息、依赖选项、编译标志等

元功能包(Meta Packages)

  • 组织多个用于同一目的功能包

4. ROS命令行工具的使用

4.1 常用命令

  • rostopic
  • rosservice
  • rosnode
  • rosparam
  • rosmsg
  • rossrv
  • rosrun 功能包 功能包节点

4.2 rqt_graph

4.3 rosnode

rosnode list 把系统所有节点显示出来

rosnode info /turtlesim 答打印节点信息

4.4 rostopic(两下Tab补全)

rostopic list 系统的所有话题

rostopic pub -r 10 (发布频率) /turtle1/cmd_vel(话题名) XXXXX(发送数据内容) 可以发布的内容

4.5 rosmsg

rosmsg show 消息

4.6 rosservice

rosservice list

rosservice call /spawn (可以再开一个服务)

4.7 rosbag

应用场景:保存一次飞行记录,然后复现

话题记录rosbag record -a -O cmd_record

话题浮现rosbag play cmd_record.bag

5. 创建工作空间与功能包

5.1 工作空间(workspace)

工作空间是一个存放工程开发相关的文件夹

  • src:代码空间
  • build:编译空间
  • devel:开发空间
  • Install:安装空间

创建工作空间

mkdir -p ./catkin_ws/src
cd ./catkin_ws/src
catkin_init_workspace

编译工作空间

cd ./catkin_ws/
catkin_make
catkin_install

设置环境变量

source devel/setup.bash

检查环境变量

echo $ROS_PACKAGE_PATH

5.2 功能包

catkin_create_pkg<package_name>[depend1][depend2][depend3]()

创建功能包

cd ./catkin_ws/src
catkin_create_pkg  test_pkg  msgs rospy roscpp#cpp c++程序,py python程序

编译功能包

cd ./catkin_ws
catkin_make
source ./catkin_ws/devel/setup.bash

6. 发布者Publicsher的编程实现

1.创建功能包

cd ./catkin_ws/src
catkin_create_pkg  learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

2.在src下写cpp

如何实现一个发布者

  • 初始化ROS节点
  • 向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型
  • 创建消息数据
  • 按照一定频率循环发布消息

文件名 velocity_publisher.cpp

/**
*该例程将发布turtle1/cmd_vel话题,消息类型为geometry_msgs::Twist
*/
#include <ros/ros.h>
#include <geometry/Twist.h>
int main(int argc, char **argv)
{
    //ROS节点初始化
    ros::init(argc,argv,"velocity_publisher");
    //创建节点句柄
    ros::NodeHandle n;
    //创建一个Publisher,发布名为/turtle/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度为10
    ros::Publisher turtle_vel_pub=n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",10);
    //设置循环频率
    ros::Rate loop_rate(10);
    
    int count=0;
    while(ros::ok())
    {
        //初始化geometry_msgs::Twist类型的消息
        gepmetry_msgs::Twist vel_msg;
        vel_msg.linear.x=0.5;
        vel_msg.angular.z=0.2;
        
        //发布消息
        turtle_vel_pub.publish(vel_msg);
        ROS_INFO("Publish turtle velocity command[%o.2f m/s,%0.2 rad/s]",vel_msg.linear.x,vel_msg.angual.z);
        
        //按照循环频率延时
        loop_rate.sleep();
    }
    return 0;
}

3.配置CMaklelists.txt中的编译规则

  • 设置需要编译的代码和生成的可执行文件
  • 设置链接库

放在Build一栏

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

4.编译并运行发布者

cd ./catkin_ws
catkin_make
source devel/setup.bash
roscore

rosrun turtlesim turtlesim_node

rosrun learning_topic velocity_publisher

7. 订阅者Subscriber的编程实现

1.上一讲的learning_topic功能包

2.在src下写cpp

如何实现一个订阅者

  • 初始化ROS节点
  • 订阅需要的话题
  • 循环等待话题消息,接收到消息后进入回调函数
  • 在会点函数中完成消息处理

文件名 pose_subscriber.cpp

/**
*该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose
*/

#include <ros/ros.h>
#include <turtlesim/Pos.h>
void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
    ROS_INFO("Turtle pose: x:%0.2f , y:%0.2f",msg->x,msg->y);
}

int main(int argc, char **argv)
{
    //初始化ROS节点
    ros::init(argc,argv,"pose_subscriber");
    //创建句柄
    rose::NodeHandle n;
    //创建一个Subscriber,订阅名为turtle1/pose的topic,注册回调函数poseCallback
    rose::Subscriber pos_pub=n.subscribe("/turtle1/pose",10,poseCallback);
    //循环等待回调函数
    ros::spin();
    
    return 0;
    
}

3.配置CMaklelists.txt中的编译规则

  • 设置需要编译的代码和生成的可执行文件
  • 设置链接库
add_executable(pose_subcriber  src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber${catkin_LIBRARIES})

4.编译并运行订阅者

cd ./catkin_ws
catkin_make
source devel/setup.bash
roscore

rosrun turtlesim turtlesim_node

rosrun learning_topic velocity_publisher

rosrun learning_topic pose_subcriber

8. 话题消息的定义与使用

上面两个都是源码文件中有的消息类型,这节主要是自定义数据类型

1.定义msg文件

在learning topic中创建msg文件夹,所有msg都放在这里

在其中touch Person.msg

string name
uint8 sex
uint8 sex

uint unknown=0
uint male=1
uint female=2

2.在package.xml中添加功能包依赖

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

3.CMakeLists.txt添加编译选项

find_package(...... ){
xxxxx
xxxxx
message_generation
}


add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std msgs)


catkin package(){
message runtime
}

4.测试

person_publisher.cpp

/**
*该例程将发布/Person_info话题,消息类型为learning_topic::Person
*/
#include <ros/ros.h>
#include <learning_topic/Person.h>
int main(int argc, char **argv)
{
    //ROS节点初始化
    ros::init(argc,argv,"person_publisher");
    //创建节点句柄
    ros::NodeHandle n;
    //创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度为10
    ros::Publisher turtle_vel_pub=n.advertise<learning_topic::Person>("/turtle1/cmd_vel",10);
    //设置循环频率
    ros::Rate loop_rate(1);
    
    int count=0;
    while(ros::ok())
    {
        //初始化learning_topic::Person类型的消息
        learning_topic::Person person_msg;
        person_msg.name="tina";
        person_msg.age=18;
        person_msg.sex= learning_topic::Person::male;
        
        //发布消息
        turtle_vel_pub.publish(person_msg);
        ROS_INFO("Publish Person_Info:name:%s	age:%d	sex:%d",person_msg.name,person_msg.age,person_msg.sex);
        
        //按照循环频率延时
        loop_rate.sleep();
    }
    return 0;
}

person_subscriber.cpp

/**
*该例程将订阅/person_info话题,消息类型learning_topic::Person
*/

#include <ros/ros.h>
#include <learning_topic/Person.h>
void personCallback(const learning_topic::Person::ConstPtr& msg)
{
    ROS_INFO("Subcriber person_info::name:%s	age:%d	sex:%d",msg->name,msg->age,msg->sex);
}

int main(int argc, char **argv)
{
    //初始化ROS节点
    ros::init(argc,argv,"person_subscriber");
    //创建句柄
    rose::NodeHandle n;
    //创建一个Subscriber,订阅名为person_info的topic,注册回调函数personCallback
    rose::Subscriber person_info_pub=n.subscribe("/person_info",10,personCallback);
    //循环等待回调函数
    ros::spin();
    
    return 0;
    
}

5.编译并执行

配置CMaklelists.txt中的编译规则

  • 设置需要编译的代码和生成的可执行文件
  • 设置链接库
  • 添加依赖项
add_executable(person_publisher  src/person_publisher.cpp)
target_link_libraries(person_publisher${catkin_LIBRARIES})
add_dependencies(person_publisher${PROJECT_NAME}_generate_messages_cpp)


add_executable(person_subscriber  src/person_subscriber.cpp)
target_link_libraries(person_subscriber${catkin_LIBRARIES})
add_dependencies(person_subscriber${PROJECT_NAME}_generate_messages_cpp)
cd ./catkin_ws
catkin_make
source devel/setup.bash
roscore

rosrun learning_topic person_publisher

rosrun learning_topic person_subscriber

6.关闭rosmaster仍能运行,因为已经帮助建立连接了

9. 客户端Client的编程实现

1.创建功能包

cd ./catkin_ws/src
catkin_creat_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim

2.在learning_service/src下实现一个客户端

  • 初始化ROS节点
  • 创建一个Client实例
  • 发布服务请求数据
  • 等待Server处理后的应答结果

turtle_spawn.cpp

/**
*该例程将请求/spawn服务,服务数据类型turtlesim:Spawn
*/
#include <ros/ros.h>
#include <turtlesim/Spawn.h>
int main(int argc,char **argv)
{
    //初始化ROS节点
    ros::init(argc,argv,"turtle_spawn");
    //创建节点句柄
    ros::NodeHandle node;
    //发现/spawn服务后,创建一个服务客户端,连接为/spawn的service
    ros::service::waitForservice("/spawn");
    ros::serviceClient add_turtle=node.serviceClient<turtles::Spaen>("/spawn");
    //初始化turtlesim::Spawn的service
	turtlesim::Spawn srv;
    srv.request.x=2.0;
    srv.request.y=2.0;
    srv.request.name="turtle2";
    
    //请求服务调用
    ROS_INFO("Call service to spawn turtle[x:%0.6f,y:%0.6f,name:%s]",srv.request.x,srv.request.y,srv.request.name.c_str());
    add_turtle.call(srv);
    
    //爱你是服务调用结果
    ROS_INFO("Spawn turtle successfully[name:%s]".srv.respomse.name.c_str());
    return 0;
}  

3.cmakelist.txt

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

10.服务端Server的编程实现

2.在learning_service/src下实现一个客户端

  • 初始化ROS节点
  • 创建一个Server实例
  • 循环等待服务请求,进入回调函数
  • 在回调函数中完成服务功能的处理,并反馈应答数据

turtle_command_server.cpp

/**
*该例程将执行/turtle_command服务,服务数据类型std_srvs/Trigger
*/
#include <ros/ros.h>
#include <geometry/Twist.h>
#include <std_srvs/Trigger.h>

ros::Publisher turtle_vel_pub
bool pubCommand =fasle;

//service回调函数,输出参数req,输出参数res
bool commandCallback(std_srvs::Trigger::Request &req,std_srvs::Trigger::Response &res)
{
    pubCommand=!pubCommand;
    //显示请求数据
    ROS_INFO("Publish turtle velocity command[%s]",pubCommand=ture?"Yes":"No");
    //设置反馈数据
    res.sucess=true;
    res.message="change turtle command state!";
    return ture;    	
}

int main(int argc,char **argv)
{
    //ROS节点初始化
  ros::init(argc,argv,"turtle_command_server");
   //创建节点句柄
    ros::NodeHandle n;
    //创建一个名为/turtle_command的server,注册回调函数commandCallback
    ros::ServiceServer command_service = n.advertiseService("/turtle_command",commandCallback);
    //创建一个Publicsher,发布名为/turtle1/cmd_vel,消息类型为geometry_msgs::Twist,队列长度10
    turtle_vel_pub=n.advertise<gemotry_msgs::Twist>("/turtle1/cmd_vel",10);
    //循环等待回调函数
    ROS_INFO("Ready to receive turtle command");
    //设置循环的频率
    ros::Rate loop_rate(10);
    while(ros::ok())
    {
        //查看一次回调函数队列
        ros::spinOnce();
        //如果标志为ture,则发布速度指令
        if(pubCommand)
        {
         	geometry_msgs::Twist vel_msg;
            vel_msg.liner.x=0.5;
            vel_msg.angular.z=0.2;
           turtle_vel_pub.publish(vel_msg);
        }
        
        //按照循环频率延时
        loop_rate.sleep();
    }
}

3.cmakelist.txt

加到上节那个

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

11. 服务数据的定义与使用

1.定义src文件

在src中创建文件夹srv

Person.srv

string name
uint8 age
uint8 sex

uint8 unknown=0
uint8 male=1
uint8 female=2
---
string result

2.在package.xml中添加功能包依赖

<build_depend>message_generation<build_depend>
<exec_depend>message_runtime</exec_denpend>

3.在cmakelists.txt

find_package
{
....
message_generation
}

add_service_files(FILES Person.srv)
generate_messages(DEPENDENCIES std_msgs)

catkin_package(.... message_runtime)


4.client与server

person_client.cpp

/**
*该例程将请求/show_person服务,服务数据类型learning_service::Person
*/
#include <ros/ros.h>
#include <learning_service/Person.h>
int main(int argc,char **argv)
{
    //初始化ROS节点
    ros::init(argc,argv,"person_client");
    //创建节点句柄
    ros::NodeHandle node;
    //发现/spawn服务后,创建一个服务客户端,连接为/show_spawn的service
    ros::service::waitForservice("/show_spawn");
    ros::serviceClient person_client=node.serviceClient<learning_service::Person>("/show_spawn");
    
    //初始化learning_service::Person的请求数据
	learning_service::Person srv;
    srv.request.name="TOM";
    srv.request.age=28;
    srv.request.sex=learning_service::Person::Request::male;
    
    //请求服务调用
    ROS_INFO("Call service to show_spawn [name:%s,age:%d,sex:%d]",srv.request.name,srv.request.age,rv.request.sex);
    person_client.call(srv);
    
    //显示的是服务调用结果
    ROS_INFO("show person result:%s".srv.response.result.c_str());
    return 0;
}  

person_server.cpp

/**
*该例程将执行/show_person服务,服务数据类型learning_service::Person
*/
#include <ros/ros.h>
#include <learning_service/Person.h>


//service回调函数,输出参数req,输出参数res
bool personCallback(learning_service::Person::Request &req,learning_service::Person::Response &res)
{
    //显示请求数据
    ROS_INFO("Person: name:%s	age:%d	sex:%d",req.name.c_str(),req.age,req.sex);
    //设置反馈数据
    res.result="ok";
    return ture;    	
}

int main(int argc,char **argv)
{
    //ROS节点初始化
  ros::init(argc,argv,"person_server");
   //创建节点句柄
    ros::NodeHandle n;
    //创建一个名为/show_person的server,注册回调函数personCallback
    ros::ServiceServer person_service = n.advertiseService("/show_person",personCallback);
    //循环等待回调函数
    ROS_INFO("Ready to show person information");
	ros::spin();
    return 0;
}

5.cmakelist.txt

12. 参数的使用与编程方法

1.创建功能包

cd ./catkin_ws/src
catkin_create_pkg learning_parameter roscpp rospy std_srvs

2.rosparam

  • rosparam list

    列出当前多少参数

  • rosparam get param_key

    显示某个参数值

  • rosparam set param_key param_value

    保存参数到文件

  • rosparam dump file_name.yaml

    从文件读取参数

  • rosparam load file_name

    删除参数

  • rosparam delete param_key

3.程序实现

13.ROS中的坐标系管理系统

TF功能包能干什么?

  • 五秒钟之前,机器人的头部坐标系相对于全局坐标系的关系事怎样的?
  • 机器人夹取的物体相对于机器人中心坐标系的位置在哪里?
  • 机器人中心坐标系相对于全局坐标系的位置在哪里

TF坐标变换如何实现?

  • 广播TF变换
  • 监听TF变换

机器人中的坐标变换

sudo apt_get install ros-melodic-turtle-tf
roslaunch turtle_tf turtle_tf_demo.lauch
rosrun turtlesim turtle_teleop_key
rosrun tf view_frames

14. tf坐标系广播与监听的编程实现

1.创建功能包

cd ./catkin_ws/src
catkin_create_pkg learning_tf roscpp rospy tf_turtlesim

2.程序tf广播实现

  • 定义TF广播器(TransformBroadcaster)
  • 创建坐标变换值
  • 发布坐标变换(sendTransform)
  • turtle_tf_broadcaster.cpp
/**
*该例程产生tf数据,并计算、发布Turtle2的速度指令
*/
#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <turtlesim/Pose.h>

std::string turtle_name;
void poseCallback(const turtlesim::posConstPtr& msg)
{
	//创建tf的广播器
	static tf::TransformBroadcaster br;
	
	//初始化tf数据
	tf::Tramsform transform;
    //tf中tramsform就保存了trtule相对于world的平面坐标平移关系
	transform.setOrigin(tf::vector3(msg->x,msg->y,0.0));
	tf::Quaternion q;
    //tf中Quaternion就保存了Trtule相对于world的旋转关系
	q.setRPY(0,0,msg->theta);
	transform.setRotation(q);
	
	//广播world与海龟坐标系之间的tf数据
	br.sendTransform(tf::StampedTransform(transform,ros::Time::now(),"world",turtle_name));
}

int main(int argc,char** argv)
{
	//初始化ROS节点
    ros::init(argc,argv,"my_tf_broadcaster");
    
    //输入参数作为海龟的名字
    if(argc!=2)
    {
        ROS_ERROR("need turtle name as argument");
        return -1;
    }
    
    turtle_name=argv[1];
    
    //订阅海龟的位置话题
    ros::NodeHandle node;
    ros::Subscriber sub=node.subscribe(turtle_name+"/pos",10,&poseCallback);
    ros::spin();
    return 0;
}

3.如何实现一个TF监听器

  • 定义TF监听器(TransformListener)

  • 查找坐标变换(waitForTransform、lookupTransform)

    turtle_tf_listener.cpp

/**
*该例程监听tf数据,并计算、发布turtle2的速度指令
*/

#include <ros/ros.h>
#include <tf/tramsform_listener.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Spawn.h>

int main(int argc, char** argv)
{
    //初始化ROS节点
    ros::init(argc,argv,"my_tf_listener");
    
    //创建节点句柄
    ros::NodeHandle node;
    
    //请求产生turtle2
    ros::service::waitForService("\spawn");
    ros::ServiceClient add_turtle=node.serviceClient<turtlesim::Spawn>("/spawn");
    turtlesim::Spawn srv;
    add_turtle.call(srv);
    
    //创建发布Turtle2速度控制指令的发布者
    ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel",10);
    
    //创建tf的监听器
    tf::TransformListener listener;
    
    tf::Rate rate(10.0);
    while(node.ok())
    {
        //获取turtle1与turtle2坐标系之间的tf数据
        tf::StampedTransform transform;
        try
        {
            listener.waitForTransform("/turtle2","/turtle1",ros::Time(0),ros::Duration(3.0));
            listener.lookupTransform("/turtle2","/turtle1",ros::Time(0),transform);
        }
        catch(tf::TransformException &ex)
        {
            ROS_ERROR("%s",ex.what());
            ros::Duration(1.0).sleep();
            continue;
        }
        
        //根据turtle1与turtle2坐标系之间的位置关系,发布Turtle2的速度控制指令
        geometry_msgs::Twist vel_msg;
        vel_msg.angular.z=4.0*atan2(transform.getOrigin.y(),transform,getOrigin.x());
        vel_msg.liner.x=0.5*sqrt(pow(transform.getOrigin().x(),2)+pow(transform.getOrigin().y(),2));
        turtle_vel.publish(vel_msg);
        rate.sleep();
    }
   return 0; 
}

4.cmakelist.txt

5.编译运行

cd ./catkin_ws
catkin_make
source devel/setup.bash
rescore
rosrun turtlesim turtlesim_node
rosrun learning_tf turtle_tf_broadcaster__name:=turtbroadcaster/turtle1
rosrun learning_tf turtle_tf_broadcaster__name:=turtbroadcaster/turtle2
rosrun learning_tf turtle_tf_listener
rosrun turtlesim turtle_teleop_key

15.launch启动文件的使用方法

launch文件:通过XML文件实现多节点的配置和启动(可自动启动ROS Master)

15.1 launch文件语法

<launch>
	<node pkg="turtlesim" name="sim1" type="turtlesim_node"/>
    <node pkg="turtlesim" name="sim2" type="turtlesim_node"/>
<launch>
    
//<launch> launch文件中的根元素采用<launch>标签定义
    
//<node>启动节点
//<node pkg="package_name" name="executable_name" type="node_name"/>
    pkg:节点所在的功能包的名称
    type:节点的可执行文件名称
    name:节点运行时的名称 //这个会取代ros::init时的命的名字
    output(是否打印到当前终端),respawn(重启),required,ns,args
    
   <param name="output_frame" value="odom"/>
//<param>/<rosparam>设置ROS系统运行中的参数,存储在参数服务器中
    name:参数名字
    value:参数值
    加载参数文件中的多个参数
    <rosparam file="params.yaml" command="load" ns="params"/>
	
    <arg name="arg_name" default="arg_value"/>
//<arg>Launch文件内部的局部变量,仅限于launch文件使用
    name:参数名
   	value:参数值
    调用:
    <param name="foo" value="$(arg arg-name)"/>
    <node name="node" pkg="package" type="type" args="$(arg arg_name)"/>
    
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS 的相关文章

随机推荐

  • 解决方法:编译IMX6ULL裸机中断程序提示错误selected processor does not support `cpsid i‘ in ARM mode

    一 问题 编译IMX6ULL野火裸机中断程序出现错误 xff1a arm span class token operator span none span class token operator span eabi span class
  • IMX6ULL学习笔记(19)——时钟系统

    一 时钟系统简介 I MX6U 的系统主频为 528MHz xff0c 有些型号可以跑到 696MHz xff0c 但是默认情况下内部 boot rom 会将 I MX6U 的主频设置为 396MHz 我们在使用 I MX6U 的时候肯定是
  • IMX6ULL学习笔记(20)——UART串口使用

    一 UART简介 i MX6U 芯片具有多达 8 个 UART 外设用于串口通讯 xff0c UART 是在 USART 基础上裁剪掉了同步通信功能 xff0c 只支持异步通信 简单区分同步和异步就是看通信时需不需要对外提供时钟输出 xff
  • 解决方法:编译IMX6ULL裸机串口程序提示错误arm-none-eabi-ld: cannot find -lgcc: 没有那个文件或目录

    一 问题 编译IMX6ULL野火裸机串口程序出现错误 xff1a make span class token punctuation span span class token number 1 span span class token
  • IMX6ULL学习笔记(21)——MMDC接口使用(DDR3测试)

    一 MMDC简介 MMDC 接口与 STM32 的 FSMC 接口类似 xff0c 只不过 MMDC 接口专用于外接 DDR xff0c 并且 MMDC 外部引脚不复用 MMDC 是一个多模的 DDR 控制器 xff0c 可以连接 16 位
  • IMX6ULL学习笔记(22)——eLCDIF接口使用(TFT-LCD屏显示)

    一 TFT LCD简介 TFT LCD xff08 Thin Film Transistor Liquid Crystal Display xff09 即薄膜晶体管液晶显示器 TFT LCD 与无源 TN LCD STN LCD 的简单矩阵
  • STM32 ROS控制器底层代码讲解

    本文主要对控制器底层代码的整天架构进行讲解 控制器由两部分组成一部分是BootLoader 另一部分是APP xff1b BootLoader主要用于固件升级 xff0c APP则作为应用程序 BootLoader的地址为 0x800000
  • STM32 使用microros与ROS2通信

    本文主要介绍如何在STM32中使用microros与ROS2进行通信 xff0c 在ROS1中标准的库是rosserial 在ROS2中则是microros 目前网上的资料也有一部分了 xff0c 但是都没有提供完整可验证的demo xff
  • 用ROS自带的gazebo仿真器搭建自己的环境

    近期需要搭建一个室内仿真环境 xff0c 用于实验调试 xff0c 所以想把相关技巧记录下来 xff0c 如有错误 xff0c 还请批评指正 xff0c 谢谢 参考网页 xff1a 使用gazebo中的building editor创建一个
  • docker如何删除容器里的文件

    问题起因 为什么会有这个问题呢 xff1f 起因是要从一个es搜索引擎从另一个es搜索引擎中拷贝数据 图方便没用软件导致重启es的时候拷贝的数据 xff0c 引发了es的启动异常 解决方案 docker inspect docker ins
  • 从程序中学习EKF-SLAM(一)

    在一次课程的结课作业上 xff0c 作业要求复写一个EKF SLAM系统 xff0c 我从中学到了好多知识 作为一个典型轻量级slam系统 xff0c 这个小项目应该特别适合于slam系统入门 xff0c 可以了解到经典卡尔曼滤波器在sla
  • numpy和tensorflow的一些用法与联系

    tensorflow和numpy值的差别 在numpy中生成的np array可以直接在 debug中看到产生的具体数字 xff1b 而在tensorflow中却只是一个tensor类型 xff0c 需要调用tf Session run X
  • ubuntu18.04 安装librealsense并验证

    安装环境 OS Ubuntu 18 04 bionic Kernel x86 64 Linux 4 15 0 20 generic 安装Realsense SDK 参考https github com IntelRealSense libr
  • YOLOV3只显示一类检测结果,并输出位置信息

    YOLOV3批量检测图片 xff0c 只显示一类检测结果 xff0c 并输出位置信息保存到txt 第一步 xff1a 首先修改YOLOV3中src imge c中的void draw detections函数 这里的修改实现了保存检测类别的
  • 搭建PX4开发环境

    搭建PX4开发环境 官方网站PX4 IO xff0c 我使用的是ubuntu20 04 一 官方环境搭建 1 下载PX4固件 span class token function git span clone https github com
  • PX4二次开发——程序运行过程

    PX4二次开发 程序运行过程 一 写在前面 px4固件程序与最开始我们所学习的对单片机外设开发不同 xff0c 是因为飞行器控制系统是一个复杂的系统 xff0c 要求实时性好 xff0c 完成复杂的控制任务 xff0c 简简单单的按照之前所
  • PX4二次开发——编译与启动脚本的修改

    PX4二次开发 编译和启动脚本的修改 一 在修改之前我们先了解一下目录结构 1 1 总目录结构 上图 xff0c 是源码目录 Src xff1a 目录是源码目录存放所有的源码 xff0c 源码的查看都应该在这里 Mavlink xff1a
  • PX4二次开发——uorb订阅

    PX4二次开发 uorb订阅 一 写在前面 我们写了一个一个功能的模块 xff0c 这些模块并不是独立的 模块之间是有数据传递的 xff0c 这样才能组合到一起实现飞行控制的目的 那么解决模块之间的数据传递的方式就是通过uorb订阅的方式
  • PX4二次开发——PX4程序架构

    PX4程序架构 一 从RCS启动脚本可以看出哪些东西 启动脚本是一个神奇的东西 xff0c 它能够识别出你对应的飞机类型 xff0c 加载对应的混控器 xff0c 选择对应的姿态 位置估计程序以及控制程序 xff0c 初始化你需要的驱动程序
  • ROS

    ROS 1 ROS测试 启动ros master 打开一个终端roscore 启动小海龟仿真器 新打开一个终端rosrun turtlesim turtlesim node 启动海龟控制节点 新打开一个终端rosrun turtlesim