七、ROS-CAN通信

2023-05-16

七、ROS-CAN通信

    • 1. 测试官方样例
    • 2. 移植到ROS

1. 测试官方样例

我这里用的是CANalyst-II分析仪(创芯科技) Linux版
我的系统是:Ubuntu18.04.6 LTS
我的ROS版本:melodic
在这里插入图片描述

这个CAN设备是不用装驱动的,直接在终端输入lsusb就能查到CAN设备ID:04d8:0053 Microchip Technology, Inc.

lsusb

在这里插入图片描述

官方提供的Linux资料包里面就有二次开发样例
最重要的是libcontrolcan.so是动态链接库,调用库中的函数需要用到controlcan.h
在这里插入图片描述
将这4个文件复制到一个不含中文路径的目录下,我这里是复制到can_test这个文件夹里
在这里插入图片描述
修改main.cpp的内容:读取CAN1通道的数据(遥控器发给CAN1),并打印到终端

//功能:接收从CAN1发送过来的数据,并打印到终端



#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include "controlcan.h"

#include <ctime>
#include <cstdlib>
#include "unistd.h"


main()
{

	printf(">>this is mytestdemo !\r\n");//指示程序已运行

	if(VCI_OpenDevice(VCI_USBCAN2,0,0)==1)//打开设备
	{
		printf(">>open deivce success!\n");//打开设备成功
	}else
	{
		printf(">>open deivce error!\n");
		exit(1);
	}

	//配置CAN
	VCI_INIT_CONFIG config; 
	config.AccCode = 0x80000000;
	config.AccMask = 0xFFFFFFFF;
	config.Filter = 2;   //只接收标准帧
	config.Timing0 = 0x01; 
	config.Timing1 = 0x1C; //波特率定为250kps  0x01 0x1C
	config.Mode = 0; //正常模式		

	//初始化CAN1:VCI_InitCAN(设备类型、设备索引、CAN通道索引、CAN配置参数)
	if(VCI_InitCAN(VCI_USBCAN2,0,0,&config)!=1)
	{
		printf(">>Init CAN1 error\n");
		VCI_CloseDevice(VCI_USBCAN2,0);
	}

	if(VCI_StartCAN(VCI_USBCAN2,0,0)!=1)
	{
		printf(">>Start CAN1 error\n");
		VCI_CloseDevice(VCI_USBCAN2,0);

	}

	//初始化用来接收的数据帧,帧结构体数组的长度设置为50
    VCI_CAN_OBJ rec[50];
	int reclen=0;
	int i,j;


	while(1)
	{

		//VCI_InitCAN(设备类型、设备索引、CAN通道索引0就是CAN1、接收数组的首指针rec、接收数组的长度50、保留参数)	
		if((reclen = VCI_Receive(VCI_USBCAN2,0,0,rec,50,200)) >= 0)//调用接收函数,如果有数据,则进行处理
		{
			for(i=0; i<reclen; i++)
			{
				//打印数据
				printf("data:0x");	
				for( j= 0; j < rec[i].DataLen; j++ )
				{
					printf(" %02X", rec[i].Data[j]); //%02X表示用2个位置数据一个16进制数
				}
				printf("\n");
			}
		}
	}
}

然后将libcontrolcan.so动态链接库的绝对路径添加到Makefile中
就可以将这个main.cpp编译成可执行文件test2333,可执行文件名可以自定义

all:

	g++ -o test2333 main.cpp /home/yao/My_Ros_WorkSpace/can_test/libcontrolcan.so  -lpthread 

clean:
	rm -f *.o

最后在终端中编译和执行即可

lsusb
cd /home/yao/My_Ros_WorkSpace/can_test
rm test2333
make clean && make
sudo ./test2333

在这里插入图片描述
遥控器↑:02 01 00 00 00 00 00 00
遥控器↓:02 02 00 00 00 00 00 00
遥控器←:02 04 00 00 00 00 00 00
遥控器→:02 08 00 00 00 00 00 00

OK,到这里说明我们的设备和程序都是可以正常工作的,没有问题!

特别注意:CAN1口旁边的2个120Ω上拉电阻,必须保证至少一个是拨到ON档
否则没办法接收CAN1口发送过来的数据
在这里插入图片描述

2. 移植到ROS

接下来,将这部分代码移植到ROS系统下

  • 首先创建工作空间
    用VScode打开工作空间,需要进行配置:看我前面的文章
cd ~/My_Ros_WorkSpace
mkdir can_workspace
cd  can_workspace
mkdir src
cd src
catkin_init_workspace
cd ..
catkin_make
catkin_make install
code .
  • 然后创建功能包
    选中src,右键Create Catkin Package
    录入功能包名字"can_pkg",回车
    录入依赖"roscpp rospy std_msgs",再回车

  • 创建节点:读取CAN1的数据
    选中can_pkg→src,右键新建一个发布者的实现代码mycan_pub.cpp
    修改 .vscode/c_cpp_properties.json,设置 "cppStandard"为 “c++17”并保存,否则会报错

重中之重:
因为要用到libcontrolcan.so和controlcan.h,所以要将这两个文件添加到这个工作空间下

controlcan.h:

  1. 先放到can_workspace/src/can_pkg/include/can_pkg目录下
    在这里插入图片描述

  2. 然后配置includePath路径,在c_cpp_properties.json文件中添加controlcan.h所在的绝对路径 “/home/yao/My_Ros_WorkSpace/can_workspace/src/can_pkg/include/**”
    在这里插入图片描述

  3. 然后就可以在mycan_pub.cpp中调用这个头文件了,注意引用头文件的写法,需要将头文件的相对路径加进来,否则会报错,应该这样写:#include “can_pkg/controlcan.h”

  4. 这样就可以调用controlcan.h中声明的函数编写代码了:

#include <ros/ros.h>
#include <std_msgs/String.h>

#include "can_pkg/controlcan.h"

using namespace std; //声明命名空间

int main(int argc, char** argv)
{
    //初始化,节点名为can_publisher
    ros::init(argc, argv,"can_publisher");

	if(VCI_OpenDevice(VCI_USBCAN2,0,0)==1)//打开设备
	{
        ROS_INFO_STREAM(">>open deivce success!");//打开设备成功
	}else
	{
        ROS_INFO_STREAM(">>open deivce error!");//打开设备成功
		exit(1);
	}

	//配置CAN
	VCI_INIT_CONFIG config; 
	config.AccCode = 0x80000000;
	config.AccMask = 0xFFFFFFFF;
	config.Filter = 2;   //只接收标准帧
	config.Timing0 = 0x01; 
	config.Timing1 = 0x1C; //波特率定为250kps  0x01 0x1C
	config.Mode = 0; //正常模式		

	//初始化CAN1:VCI_InitCAN(设备类型、设备索引、CAN通道索引、CAN配置参数)
	if(VCI_InitCAN(VCI_USBCAN2,0,0,&config)!=1)
	{
        ROS_INFO_STREAM(">>Init CAN1 error");
		VCI_CloseDevice(VCI_USBCAN2,0);
	}

	if(VCI_StartCAN(VCI_USBCAN2,0,0)!=1)
	{
        ROS_INFO_STREAM(">>Start CAN1 error");
		VCI_CloseDevice(VCI_USBCAN2,0);
	}

	//初始化用来接收的数据帧,帧结构体数组的长度设置为50
    VCI_CAN_OBJ rec[50];
	int reclen=0;
	int i,j;


	while(1)
	{

		//VCI_InitCAN(设备类型、设备索引、CAN通道索引0就是CAN1、接收数组的首指针rec、接收数组的长度50、保留参数)	
		if((reclen = VCI_Receive(VCI_USBCAN2,0,0,rec,50,200)) >= 0)//调用接收函数,如果有数据,则进行处理
		{
			//顺便将接收到的数据打印到终端
			for(i=0; i < reclen; i++)
			{
                printf("data:0x");
				for( j= 0; j < rec[i].DataLen; j++ )
				{
                    printf(" %02X", rec[i].Data[j]); //%02X表示用2个位置数据一个16进制数
				}
				printf("\n");
			}
		}
	}
    return 0;
}

libcontrolcan.so:

  1. 在功能包can_pkg目录下创建一个lib文件夹
  2. 将libcontrolcan.so复制到刚刚新建的lib文件夹下面
    在这里插入图片描述
  • 配置CMakeLists.txt
  1. 解除#include的注释:可以让编译器去include下找到can_pkg/controlcan.h
## 解除#include的注释:去找头文件
include_directories(
include
  ${catkin_INCLUDE_DIRS}
)
  1. 指定动态链接库libcontrolcan.so的访问路径
## 手动添加link_directories():指定动态链接库的访问路径为功能包can_pkg下的lib
link_directories(
  lib
  ${catkin_LIB_DIRS}
)
  1. 最后就是指定生成可执行文件和链接库
# 生成可执行文件
add_executable(mycan_pub src/mycan_pub.cpp)
# 链接库
target_link_libraries(mycan_pub  
  ${catkin_LIBRARIES}
  controlcan #链接动态链接库libcontrolcan.so,但是要注意这里写的时候仅保留创建时所用到的名称,所以要去掉前缀lib和后缀.so
  )
  • 编译执行
    Ctrl + S保存,Ctrl + Shift +B编译
  1. 终端1
roscore
  1. 终端2
source devel/setup.bash
rosrun can_pkg mycan_pub

报错:error setting config #1: could not set config 1: Operation not permitted
原因:这是因为Linux系统下将涉及到usb底层驱动的调用,运行时,一定要加sudo获取权限运行,否则USB
设备没有权限操作,比如之前运行那个用gcc编译的可执行文件test2333时,我也是加了sudo的

sudo ./test2333

但是用rosrun can_pkg mycan_pub启动节点的时候,貌似没办法加sudo,所以需要配置USB权限:

方法一:

  1. 创建一个新的 udev 规则,名称取为:99-myusb.rules
    注意:数字 99 最好不要改动,否则可能设置失败,而且要加 sudo
sudo vi /etc/udev/rules.d/99-myusb.rules
  1. 把以下两行代码复制到新建的 99-myusb.rules 文件中
    注意:按键盘上 Insert 键切换到“代替”输入模式,然后粘贴
##
ACTION=="add",SUBSYSTEMS=="usb", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="0053",
GROUP="users", MODE="0777"
  1. 按一次“Esc”键
  2. 直接输入“:wq”回车,即保存退出
  3. 插拔一下 USBCAN 设备或重启一下电脑
  4. 就可以不加 sudo 权限运行程序了,或者ROS下用rosrun启动节点也不会报错了

方法二:

cd /etc/udev/rules.d
sudo touch 99-myusb.rules
sudo gedit 99-myusb.rules
## 将下面这两句代码复制到文件中
ACTION=="add",SUBSYSTEMS=="usb", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="0053",
GROUP="users", MODE="0777"
## 重启电脑即可生效
  • 升级节点:读取完CAN1的数据,根据遥控器发过来的数据,将控制指令输出到CAN2,以便后续的控制操作
  1. 硬件连接:CANalyst-II的CAN1连接遥控器、CAN2可以再外接一个CANalyst-II并连到Windows系统,这样就可以将CAN2输出的控制指令在Windows系统上的USB_CAN TOOL调试软件上显示出来。注意:所有CAN口的上拉电阻都需要拨到ON档
  2. 代码如下:
#include <ros/ros.h>
#include <std_msgs/String.h>

#include "can_pkg/controlcan.h"

using namespace std; //声明命名空间

//初始化启动CAN1并启动
bool Init_CAN1(int nDeviceType, int nDeviceInd, int nCANInd, VCI_INIT_CONFIG config) {
	VCI_ResetCAN(nDeviceType, nDeviceInd, nCANInd);
    if (VCI_InitCAN(nDeviceType, nDeviceInd, nCANInd, &config) != 1)
    {
        VCI_CloseDevice(nDeviceType, nDeviceInd);
        ROS_INFO_STREAM(">>Init CAN1 error");
        return(0);
    }
    VCI_ClearBuffer(nDeviceType, nDeviceInd, nCANInd);
    if (VCI_StartCAN(nDeviceType, nDeviceInd, nCANInd) != 1)
    {
        VCI_CloseDevice(nDeviceType, nDeviceInd);
        ROS_INFO_STREAM(">>Start CAN1 error");
        return(0);
    }
	else
	{
    	ROS_INFO_STREAM(">>Start CAN1 success");
    	return(1);
	}
}

//初始化启动CAN2并启动
bool Init_CAN2(int nDeviceType, int nDeviceInd, int nCANInd, VCI_INIT_CONFIG config) {
	VCI_ResetCAN(nDeviceType, nDeviceInd, nCANInd);
    if (VCI_InitCAN(nDeviceType, nDeviceInd, nCANInd, &config) != 1)
    {
        VCI_CloseDevice(nDeviceType, nDeviceInd);
        ROS_INFO_STREAM(">>Init CAN2 error");
        return(0);
    }
    VCI_ClearBuffer(nDeviceType, nDeviceInd, nCANInd);
    if (VCI_StartCAN(nDeviceType, nDeviceInd, nCANInd) != 1)
    {
        VCI_CloseDevice(nDeviceType, nDeviceInd);
        ROS_INFO_STREAM(">>Start CAN2 error");
        return(0);
    }
	else
	{
    	ROS_INFO_STREAM(">>Start CAN2 success");
    	return(1);
	}
}


int main(int argc, char** argv)
{
    //初始化,节点名为can_publisher
    ros::init(argc, argv,"can_publisher");

	//根据遥控器指令发送相应的控制指令
	const unsigned char a0[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; //默认
    const unsigned char a1[] = { 0xF4,0x01,0x00,0x00,0x00,0x00,0x00,0x00 }; //↑
    const unsigned char a2[] = { 0x00,0x00,0xF4,0x01,0x00,0x00,0x00,0x00 }; //↓
    const unsigned char a3[] = { 0x00,0x00,0x00,0x00,0xF4,0x01,0x00,0x00 }; //←
    const unsigned char a4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0xF4,0x01 }; //→

	//打开和初始化设备的一些参数配置
	int nDeviceType = 4; //设备类型:CANalyst-II就用4
    int nDeviceInd = 0; //设备索引:1个USB-CAN适配器就是0
    int nCANInd0 = 0;//CAN1
    int nCANInd1 = 1;//CAN2

    //打开设备:注意一个设备只能打开一次
	if(VCI_OpenDevice(nDeviceType,nDeviceInd,0)==1)
	{
        ROS_INFO_STREAM(">>open deivce success!");//打开设备成功
	}else
	{
        ROS_INFO_STREAM(">>open deivce error!");//打开设备失败
		exit(1); //退出整个程序,终止进程:返回1给操作系统说明是非正常运行导致程序退出
	}

	//配置CAN
	VCI_INIT_CONFIG config; 
	config.AccCode = 0x80000000;
	config.AccMask = 0xFFFFFFFF;
	config.Filter = 2;   //只接收标准帧
	config.Timing0 = 0x01; 
	config.Timing1 = 0x1C; //波特率定为250kps  0x01 0x1C
	config.Mode = 0; //正常模式		

	
	//初始化用来接收的数据帧,帧结构体数组的长度设置为50
	int num = 50;
    VCI_CAN_OBJ rec[num];
	int reclen = 0;
	int i,j,k, order;

	//初始化用来发送的数据帧,帧结构体数组的长度设置为1
	VCI_CAN_OBJ send[1];
	send[0].ID = 0; //帧ID
	send[0].SendType = 0; //发送帧类型:0为正常发送
	send[0].RemoteFlag = 0; //0为数据帧,1为远程帧
	send[0].ExternFlag = 0; //0为标准帧,1为拓展帧
	send[0].DataLen = 8; //数据长度8字节

    //CAN1和CAN2双通道初始化(设备类型、设备索引、CAN通道索引、CAN配置参数)
    if (Init_CAN1(nDeviceType, nDeviceInd, nCANInd0, config) && Init_CAN2(nDeviceType, nDeviceInd, nCANInd1, config))
	{
		while(1)
		{
			//延时20ms:在满足应用的时效性情况下,尽量降低调用VCI_Receive频率,每隔30ms调用一次VCI_Receive为宜
			usleep(20000);

			//VCI_Receive(设备类型、设备索引、CAN通道索引0就是CAN1、接收数组的首指针rec、接收数组的长度50、保留参数)	
			if((reclen = VCI_Receive(nDeviceType,nDeviceInd,nCANInd0,rec,num,200)) >= 0)//调用接收函数,如果有数据,则进行处理
			{

				for(i=0; i < reclen; i++)
				{
					//接收到的遥控器指令
					order = (int)rec[i].Data[1] + (int)rec[i].Data[2];

					//先将接收到的遥控器指令打印到终端
					printf("data:0x");
					for( j= 0; j < rec[i].DataLen; j++ )
					{
						printf(" %02X", rec[i].Data[j]); //%02X表示用2个位置数据一个16进制数
					}
					printf("\n");

					//然后根据遥控器的指令,让CAN2发布相应的控制指令
					switch (order) 
					{
						case 0: //默认
						{
							for (k = 0; k < 8; k++)
							{
								send[0].Data[k] = a0[k];
							}
							VCI_Transmit(nDeviceType, nDeviceInd, nCANInd1, send, 1);
							break;
						}
						case 1: //↑
						{
							for (k = 0; k < 8; k++)
							{
								send[0].Data[k] = a1[k];
							}
							VCI_Transmit(nDeviceType, nDeviceInd, nCANInd1, send, 1);
							break;
						}
						case 2: //↓
						{
							for (k = 0; k < 8; k++)
							{
								send[0].Data[k] = a2[k];
							}
							VCI_Transmit(nDeviceType, nDeviceInd, nCANInd1, send, 1);
							break;
						}
						case 4: //←
						{
							for (k = 0; k < 8; k++)
							{
								send[0].Data[k] = a3[k];
							}
							VCI_Transmit(nDeviceType, nDeviceInd, nCANInd1, send, 1);
							break;
						}
						case 8: //→
						{
							for (k = 0; k < 8; k++)
							{
								send[0].Data[k] = a4[k];
							}
							VCI_Transmit(nDeviceType, nDeviceInd, nCANInd1, send, 1);
							break;
						}
						default: //检查和处理错误情况
						{
							for (k = 0; k < 8; k++)
							{
								send[0].Data[k] = a0[k];
							}
							VCI_Transmit(nDeviceType, nDeviceInd, nCANInd1, send, 1);
							break;
						}
					}

				}
			}
		}
	}
    return 0;
}
// roscore
// source devel/setup.bash
// rosrun can_pkg mycan_pub
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

七、ROS-CAN通信 的相关文章

  • SLAM-hector_slam 简介与使用

    hector slam功能包使用高斯牛顿方法 不需要里程计数据 只根据激光信息便可构建地图 所以他的总体框架如下 hector slam功能包 hector slam的核心节点是hector mapping 它订阅 scan 话题以获取SL
  • ROS诸多调试工具总结1

    ROS有许多调试工具来为ROS调试你的工具 1 rosnode 参数 用法 作用 list rosnode list 查看当前运行了哪些节点 info rosnode info node name 查看该节点发布 接受哪些话题以及服务 ki
  • Ubuntu下vscode配置ROS环境

    摘要 最近准备放弃用clion开发ROS使用更主流的vscode 整理一下在ubuntu18 04下的VSCode安装和ROS环境配置流程 安装 方法一 软件商店安装 个人还是推荐使用ubuntu软件下载vscode 简单不容易出错 方法二
  • ModuleNotFoundError: No module named ‘rosbag‘

    1 ModuleNotFoundError No module named rosbag File opt ros kinetic lib python2 7 dist packages roslib launcher py line 42
  • ROS rosdep update 出错方法 不需要翻墙切换之类的解决方法 ‘https://raw.githubusercontent.com/ros/rosdistro/master/inde

    系统 ubuntu18 rosdep update参考的这篇文章 https blog csdn net weixin 43311920 article details 114796748 utm source app app versio
  • Ubuntu 周立功CAN分析仪 USBCAN-II 驱动

    首先从官网https www zlg cn Index Search search key linux的下载资料界面下载 Linux驱动 USBCAN I I II II 2A I MINI安装驱动 USBCAN II新版驱动基于libus
  • Raspberry Pi 上 ROS 服务器/客户端通过GPIO 驱动硬件

    ROS 服务 现在 想象一下你在你的电脑后面 你想从这个服务中获取天气 你 在你身边 被认为是客户端 在线天气服务是服务器 您将能够通过带有 URL 的 HTTP 请求访问服务器 将 HTTP URL 视为 ROS 服务 首先 您的计算机将
  • 树莓派配置wifi做热点方法

    http wiki jikexueyuan com project raspberry pi wifi html
  • 最快实现一个自己的扫地机

    作者 良知犹存 转载授权以及围观 欢迎关注微信公众号 羽林君 或者添加作者个人微信 become me 扫地机介绍 扫地机器人行业本质是技术驱动型行业 产品围绕导航系统的升级成为行业发展的主旋律 按功能划分 扫地机器人分为四大系统 即导航系
  • 服务数据的定义和使用

    1 自定义数据服务 在包下创建srv文件夹 在文件夹下创建Person srv 在Person srv下输入以下内容 代表数据类型 string name uint8 age uint8 sex uint8 unknown 0 uint8
  • 《学习篇》学会这18个常用ROS命令集合就能入门ROS了

    常用ROS命令概述 ROS常用命令可以按照其使用场景分为ROSshell命令 ROS执行命令 ROS信息命令 ROS catkin命令与ROS功能包命令 虽然很难从一开始就很熟练地使用所有的命令 但是随着使用的次数增多 你会发现常用的几个R
  • roslaunch error: ERROR: cannot launch node of type

    今天在因为github上有个之前的包更新了 重新git clone后出现了一个问题 ERROR cannot launch node of type crazyflie demo controller py can t locate nod
  • 什么是 void `std::allocator`?即:`std::allocator`

    自动生成ROS 机器人操作系统 message C 头文件包含如下类型定义 typedef std msgs Header
  • Kinect / Primesense (Xtion) ROS Ubuntu 通过虚拟机 (VMware)

    由于我花了相当长的时间才弄清楚如何让 Xtion Primesense 在 VMware 上工作 所以我想在这里与大家分享 使用 Kinect 时 即使 VMware 已成功连接该设备 我也无法让 ROS 查看该设备 roslaunch o
  • 如何将曲面拟合到一组数据点并获得曲面方程

    乌班图 ROS 思维 Python程序 我正在尝试获取适合点云数据中的一组点的表面方程 数据来自激光雷达扫描仪 我在 rviz 中选择整个扫描的一部分 并获得该选择的坐标选定表面的图片 所选曲面并不总是如此线性 因为材质中可能存在轻微的曲线
  • pico示波器使用

    文章目录 Pico示波器保存波形 Pico示波器录制数据 Pico示波器解析CAN报文 Pico示波器保存波形 Pico示波器可以通过以下步骤保存波形 在示波器上选择要保存的波形 连接示波器到计算机上 可以使用USB或者Ethernet连接
  • 在 Ubuntu 18.10 上安装 ROS Melodic

    I can t是唯一对 Cosmic 与 Wayland 和 Melodic 的组合感兴趣的人 我会坦白说 我似乎已经在 XPS 13 9370 上成功管理了此操作 或者至少安装脚本 最终 成功完成 然而 有一个非常棘手的解决方法 无论结果
  • ROS安装错误(Ubuntu 16.04中的ROS Kinetic)

    中列出的步骤顺序http wiki ros org kinetic Installat 已被关注 尝试在Ubuntu 16 04中安装ROSkinetic 输入以下命令时出错 sudo apt get install ros kinetic
  • 如何使用 PyQT5 连接和分离外部应用程序或对接外部应用程序?

    我正在使用 ROS 为多机器人系统开发 GUI 但我对界面中最不想做的事情感到困惑 在我的应用程序中嵌入 RVIZ GMAPPING 或其他屏幕 我已经在界面中放置了一个终端 但我无法解决如何向我的应用程序添加外部应用程序窗口的问题 我知道
  • 在 Google Colaboratory 上运行gym-gazebo

    我正在尝试在 Google Colaboratory 上运行gym gazebo 在Colab上运行gazebo服务器 没有gui的gazebo 有问题 显示警告 Unable to create X window Rendering wi

随机推荐

  • 【杭电100题】2094 产生冠军

    原题 xff1a http acm hdu edu cn showproblem php pid 61 2094 最近很喜欢用map 把成功者 失败者都存起来 然后在成功者里把曾经失败的划掉 最后成功者里如果只剩一个人 xff0c 冠军产生
  • docker命令详解

    镜像下载 搜索镜像docker search 43 镜像名字 docker search centos 从Docker Hub中搜索符合条件的镜像 下载镜像 docker pull 43 镜像名字 docker pull centos 查看
  • uCos中的信号量机制

    文章目录 1 背景2 概述2 1 主要机制及应用2 2 同步或通信的基本方式 3 信号量3 1 主要机制及应用3 2 分类3 3 互斥信号量3 3 1 嵌套 递归 资源访问3 3 2 删除安全 3 4 各种互斥机制的比较3 5 二值信号量3
  • opencv里的几种图像数据格式(CV_8UC3,CV_32FC3,CV_64FC3等)

    opencv里的几种图像数据格式 xff08 CV 8UC3 xff0c CV 32FC3 xff0c CV 64FC3等 xff09 参考 xff1a https blog csdn net qq 29540745 article det
  • android:使用audiotrack 类播放wav文件

    参考 xff1a http mindtherobot com blog 624 android audio play an mp3 file on an audiotrack http baike baidu com view 14471
  • 逆变电路

    逆变的概念 与整流相对应 xff0c 直流电 变成 交流电 交流侧接电网 xff0c 为 有源逆变 交流侧接负载 xff0c 为 无源逆变 xff0c 本章主要讲述无源逆变 逆变与变频 变频电路 xff1a 分为 交交变频 和 交直交变频
  • windows找不到树莓派IP地址

    树莓派用网线连接电脑 xff0c 第一次正常 xff0c 而第二次用arp a找不到树莓派的地址 xff0c 网上查资料 xff0c 网络共享关闭再重新打开依旧找不到 xff0c 后来发现网络处以太网一直显示正在识别 xff0c 把以太网禁
  • unity报错NullReferenceException: Object reference not set to an instance of an object

    在做unity3d的UDP通信时 xff0c 遇到了该的错误 之前初始化用的Start xff0c 运行正常 xff0c 某天突然报错 xff0c 后面看到了文章 https blog csdn net u011185231 article
  • Unity3D UDP通信

    补一下前面遇到的问题 最近在做树莓派与Unity3D的UDP通信 xff0c 树莓派通过网线连接电脑 xff0c 设置网络共享 树莓派作为客户端 xff08 python xff09 xff0c Unity3D作为服务端 xff08 C x
  • ROS机械臂模型的调试

    用传感器串口输出数据控制虚拟机ROS中的6DOF机械臂模型 xff08 每次重新调试都需要一定的时间熟悉过程 xff0c 所以记录一下 不记录代码只记录调试过程 xff09 串口配置 传感器通过USB转TTL模块接到电脑 xff0c 在虚拟
  • openrave

    配置IKFAST求解器 xff0c 装openrave装了一天终于在差三分钟十一点的时候出来了界面 ubuntu18的boost默认1 65 xff0c 但是好像和openrave不匹配 xff0c 换成了1 58 如果后续使用没问题就来详
  • ROS1代码转ROS2

    先占个坑 xff0c 等我做完写总结
  • 四元数基本概念&&四元数3D旋转(求两个四元数的夹角)

    四元数基本概念 1 四元数定义向量形式 xff1a 模长 xff1a 2 四元数加减法 3 四元数的逆和共轭 当q是单位四元数时 xff0c 4 四元数乘法4 1 标量乘法 xff1b 标量s 四元数与标量相乘满足乘法交换律 xff1a 4
  • 树莓派安装64bit系统并安装miniconda

    树莓派安装64bit系统并安装miniconda 某机械臂只有arm64的动态链接库 xff0c 所以如题 中间过程无比曲折 xff0c 记录一下 1 安装64bit系统 1 1 下载系统 树莓派系统官网 xff1a https www r
  • 四旋翼无人机学习第23节--原理图与PCB库开源计划

    在之前的教程中 xff0c 我们学到了原理图和PCB库的绘制方法 xff0c 了解了绘制的基本方法 在之后的学习中 xff0c 我打算从头开源自己的原理图和PCB库 不定期更新 xff0c 方便大家快速的进行PCB设计 这里有几点想要说明
  • 基于openmv的无人机Apriltag动态追踪降落完整项目资料(labview+openmv+apriltag+正点原子四轴)

    前言 xff1a 之前假期做的一个小项目 xff0c 炸了好几套桨叶233 xff0c 分享出来希望能帮助更多人快速学习 使用正点原子ATK MiniFly 飞行器二次开发多旋翼Apriltag追踪 xff1b 使用LABVIEW自主设计地
  • 某公司算法岗笔试题(部分)

    今天参加了第一次笔试 xff0c 准备的不是很好 xff0c 分享几道题 1 选择题 xff1a int i 61 1 const int j 61 1 下列错误的是 xff1a const int p1 61 amp i const in
  • 五、ROS使用serial包进行串口通信

    五 ROS使用serial包进行串口通信 1 下载串口调试助手CuteCom2 下载虚拟串口模拟器socat3 下载串口调试助手minicom4 安装serial串口功能包5 创建工作空间6 创建功能包7 创建发布者8 配置CMakeLis
  • 六、ROS安装ros_canopen模块

    六 ROS安装ros canopen模块 1 查看自己的ROS版本2 下载ros canopen源码 1 查看自己的ROS版本 首先查看自己的ROS版本 xff1a 我的是melodic 终端1 roscore 终端2 rosparam l
  • 七、ROS-CAN通信

    七 ROS CAN通信 1 测试官方样例2 移植到ROS 1 测试官方样例 我这里用的是CANalyst II分析仪 创芯科技 Linux版 我的系统是 xff1a Ubuntu18 04 6 LTS 我的ROS版本 xff1a melod