Ubuntu16.04 (ROS)下通过CAN分析仪(USBCAN/CANalyst-II)调试无人车助力转向电机(1)
调试流程
1、测试USBCAN/CANalyst-II工作是否正常
2、使用PC端的上位机测试转向电机是否正常及指令测试
3、测试USBCAN/CANalyst-II提供的Linux x64的例程
4、移植Linux x64的例程到ROS功能包下
5、在ROS环境下测试转向电机的CAN协议
1、用上位机测试USBCAN/CANalyst-II工作是否正常
2、使用PC端的上位机测试转向电机是否正常及指令测试
PC 发送:
字节定义:
第一字节:控制方式
0x00:停止控制;
0x10:手动控制方式;
0x20:自动控制方式(角度控制方式)。
第二字节:保留;
第三字节:保留;
第四字节:角度高位;
第五字节:角度低位;
角度计算公式: angle =(receive[3]*256+receive[4]-1024;
第六字节:角度对中指令 0x55,不需要角度对中,此字节发 0x00 即可;
角度对中功能仅在手动控制模式下起作用;
第七字节:角速度控制,数据范围为: 20-250,对应角速度请求 120-1500 转/分;
第八字节:异或校验
3、测试USBCAN/CANalyst-II提供的Linux x64的例程
#ifndef CONTROLCAN_H
#define CONTROLCAN_H文件版本:v2.02 20190609
//接口卡类型定义#define VCI_USBCAN1 3
#define VCI_USBCAN2 4
#define VCI_USBCAN2A 4#define VCI_USBCAN_E_U 20
#define VCI_USBCAN_2E_U 21//函数调用返回状态值
#define STATUS_OK 1
#define STATUS_ERR 0#define USHORT unsigned short int
#define BYTE unsigned char
#define CHAR char
#define UCHAR unsigned char
#define UINT unsigned int
#define DWORD unsigned int
#define PVOID void*
#define ULONG unsigned int
#define INT int
#define UINT32 UINT
#define LPVOID void*
#define BOOL BYTE
#define TRUE 1
#define FALSE 0//1.ZLGCAN系列接口卡信息的数据类型。
typedef struct _VCI_BOARD_INFO{USHORT hw_Version;USHORT fw_Version;USHORT dr_Version;USHORT in_Version;USHORT irq_Num;BYTE can_Num;CHAR str_Serial_Num[20];CHAR str_hw_Type[40];USHORT Reserved[4];
} VCI_BOARD_INFO,*PVCI_BOARD_INFO; //2.定义CAN信息帧的数据类型。
typedef struct _VCI_CAN_OBJ{UINT ID;UINT TimeStamp;BYTE TimeFlag;BYTE SendType;BYTE RemoteFlag;//是否是远程帧BYTE ExternFlag;//是否是扩展帧BYTE DataLen;BYTE Data[8];BYTE Reserved[3];
}VCI_CAN_OBJ,*PVCI_CAN_OBJ;//3.定义初始化CAN的数据类型
typedef struct _INIT_CONFIG{DWORD AccCode;DWORD AccMask;DWORD Reserved;UCHAR Filter;UCHAR Timing0; UCHAR Timing1; UCHAR Mode;
}VCI_INIT_CONFIG,*PVCI_INIT_CONFIG;/ new add struct for filter /
typedef struct _VCI_FILTER_RECORD{DWORD ExtFrame; //是否为扩展帧DWORD Start;DWORD End;
}VCI_FILTER_RECORD,*PVCI_FILTER_RECORD;#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endifEXTERN_C DWORD VCI_OpenDevice(DWORD DeviceType,DWORD DeviceInd,DWORD Reserved);
EXTERN_C DWORD VCI_CloseDevice(DWORD DeviceType,DWORD DeviceInd);
EXTERN_C DWORD VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);EXTERN_C DWORD VCI_ReadBoardInfo(DWORD DeviceType,DWORD DeviceInd,PVCI_BOARD_INFO pInfo);EXTERN_C DWORD VCI_SetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);EXTERN_C ULONG VCI_GetReceiveNum(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
EXTERN_C DWORD VCI_ClearBuffer(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);EXTERN_C DWORD VCI_StartCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
EXTERN_C DWORD VCI_ResetCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);EXTERN_C ULONG VCI_Transmit(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pSend,UINT Len);
EXTERN_C ULONG VCI_Receive(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pReceive,UINT Len,INT WaitTime);EXTERN_C DWORD VCI_UsbDeviceReset(DWORD DevType,DWORD DevIndex,DWORD Reserved);
EXTERN_C DWORD VCI_FindUsbDevice2(PVCI_BOARD_INFO pInfo);#endif```cpp
在这里插入代码片
#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"VCI_BOARD_INFO pInfo;//用来获取设备信息。
int count=0;//数据列表中,用来存储列表序号。
VCI_BOARD_INFO pInfo1 [50];
int num=0;
void *receive_func(void* param) //接收线程。
{int reclen=0;VCI_CAN_OBJ rec[3000];//接收缓存,设为3000为佳。int i,j;int *run=(int*)param;//线程启动,退出控制。int ind=0;while((*run)&0x0f){if((reclen=VCI_Receive(VCI_USBCAN2,0,ind,rec,3000,100))>0)//调用接收函数,如果有数据,进行数据处理显示。{for(j=0;j<reclen;j++){printf("Index:%04d ",count);count++;//序号递增printf("CAN%d RX ID:0x%08X", ind+1, rec[j].ID);//IDif(rec[j].ExternFlag==0) printf(" Standard ");//帧格式:标准帧if(rec[j].ExternFlag==1) printf(" Extend ");//帧格式:扩展帧if(rec[j].RemoteFlag==0) printf(" Data ");//帧类型:数据帧if(rec[j].RemoteFlag==1) printf(" Remote ");//帧类型:远程帧printf("DLC:0x%02X",rec[j].DataLen);//帧长度printf(" data:0x"); //数据for(i = 0; i < rec[j].DataLen; i++){printf(" %02X", rec[j].Data[i]);}printf(" TimeStamp:0x%08X",rec[j].TimeStamp);//时间标识。printf("\n");}}ind=!ind;//变换通道号,以便下次读取另一通道,交替读取。 }printf("run thread exit\n");//退出接收线程 pthread_exit(0);
}main()
{printf(">>this is hello !\r\n");//指示程序已运行num=VCI_FindUsbDevice2(pInfo1);printf(">>USBCAN DEVICE NUM:");printf("%d", num);printf(" PCS");printf("\n");for(int i=0;i<num;i++){printf("Device:");printf("%d", i);printf("\n");printf(">>Get VCI_ReadBoardInfo success!\n");printf(">>Serial_Num:%c", pInfo1[i].str_Serial_Num[0]);printf("%c", pInfo1[i].str_Serial_Num[1]);printf("%c", pInfo1[i].str_Serial_Num[2]);printf("%c", pInfo1[i].str_Serial_Num[3]);printf("%c", pInfo1[i].str_Serial_Num[4]);printf("%c", pInfo1[i].str_Serial_Num[5]);printf("%c", pInfo1[i].str_Serial_Num[6]);printf("%c", pInfo1[i].str_Serial_Num[7]);printf("%c", pInfo1[i].str_Serial_Num[8]);printf("%c", pInfo1[i].str_Serial_Num[9]);printf("%c", pInfo1[i].str_Serial_Num[10]);printf("%c", pInfo1[i].str_Serial_Num[11]);printf("%c", pInfo1[i].str_Serial_Num[12]);printf("%c", pInfo1[i].str_Serial_Num[13]);printf("%c", pInfo1[i].str_Serial_Num[14]);printf("%c", pInfo1[i].str_Serial_Num[15]);printf("%c", pInfo1[i].str_Serial_Num[16]);printf("%c", pInfo1[i].str_Serial_Num[17]);printf("%c", pInfo1[i].str_Serial_Num[18]);printf("%c", pInfo1[i].str_Serial_Num[19]);printf("\n");printf(">>hw_Type:%c", pInfo1[i].str_hw_Type[0]);printf("%c", pInfo1[i].str_hw_Type[1]);printf("%c", pInfo1[i].str_hw_Type[2]);printf("%c", pInfo1[i].str_hw_Type[3]);printf("%c", pInfo1[i].str_hw_Type[4]);printf("%c", pInfo1[i].str_hw_Type[5]);printf("%c", pInfo1[i].str_hw_Type[6]);printf("%c", pInfo1[i].str_hw_Type[7]);printf("%c", pInfo1[i].str_hw_Type[8]);printf("%c", pInfo1[i].str_hw_Type[9]);printf("\n"); printf(">>Firmware Version:V");printf("%x", (pInfo1[i].fw_Version&0xF00)>>8);printf(".");printf("%x", (pInfo1[i].fw_Version&0xF0)>>4);printf("%x", pInfo1[i].fw_Version&0xF);printf("\n");}printf(">>\n");printf(">>\n");printf(">>\n");if(VCI_OpenDevice(VCI_USBCAN2,0,0)==1)//打开设备{printf(">>open deivce success!\n");//打开设备成功}else{printf(">>open deivce error!\n");exit(1);}if(VCI_ReadBoardInfo(VCI_USBCAN2,0,&pInfo)==1)//读取设备序列号、版本等信息。{printf(">>Get VCI_ReadBoardInfo success!\n");//printf(" %08X", pInfo.hw_Version);printf("\n");//printf(" %08X", pInfo.fw_Version);printf("\n");//printf(" %08X", pInfo.dr_Version);printf("\n");//printf(" %08X", pInfo.in_Version);printf("\n");//printf(" %08X", pInfo.irq_Num);printf("\n");//printf(" %08X", pInfo.can_Num);printf("\n");printf(">>Serial_Num:%c", pInfo.str_Serial_Num[0]);printf("%c", pInfo.str_Serial_Num[1]);printf("%c", pInfo.str_Serial_Num[2]);printf("%c", pInfo.str_Serial_Num[3]);printf("%c", pInfo.str_Serial_Num[4]);printf("%c", pInfo.str_Serial_Num[5]);printf("%c", pInfo.str_Serial_Num[6]);printf("%c", pInfo.str_Serial_Num[7]);printf("%c", pInfo.str_Serial_Num[8]);printf("%c", pInfo.str_Serial_Num[9]);printf("%c", pInfo.str_Serial_Num[10]);printf("%c", pInfo.str_Serial_Num[11]);printf("%c", pInfo.str_Serial_Num[12]);printf("%c", pInfo.str_Serial_Num[13]);printf("%c", pInfo.str_Serial_Num[14]);printf("%c", pInfo.str_Serial_Num[15]);printf("%c", pInfo.str_Serial_Num[16]);printf("%c", pInfo.str_Serial_Num[17]);printf("%c", pInfo.str_Serial_Num[18]);printf("%c", pInfo.str_Serial_Num[19]);printf("\n");printf(">>hw_Type:%c", pInfo.str_hw_Type[0]);printf("%c", pInfo.str_hw_Type[1]);printf("%c", pInfo.str_hw_Type[2]);printf("%c", pInfo.str_hw_Type[3]);printf("%c", pInfo.str_hw_Type[4]);printf("%c", pInfo.str_hw_Type[5]);printf("%c", pInfo.str_hw_Type[6]);printf("%c", pInfo.str_hw_Type[7]);printf("%c", pInfo.str_hw_Type[8]);printf("%c", pInfo.str_hw_Type[9]);printf("\n");printf(">>Firmware Version:V");printf("%x", (pInfo.fw_Version&0xF00)>>8);printf(".");printf("%x", (pInfo.fw_Version&0xF0)>>4);printf("%x", pInfo.fw_Version&0xF);printf("\n"); }else{printf(">>Get VCI_ReadBoardInfo error!\n");exit(1);}//初始化参数,严格参数二次开发函数库说明书。VCI_INIT_CONFIG config;config.AccCode=0;config.AccMask=0xFFFFFFFF;config.Filter=1;//接收所有帧config.Timing0=0x03;/*波特率125 Kbps 0x03 0x1C*/config.Timing1=0x1C;config.Mode=0;//正常模式 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);}if(VCI_InitCAN(VCI_USBCAN2,0,1,&config)!=1){printf(">>Init can2 error\n");VCI_CloseDevice(VCI_USBCAN2,0);}if(VCI_StartCAN(VCI_USBCAN2,0,1)!=1){printf(">>Start can2 error\n");VCI_CloseDevice(VCI_USBCAN2,0);}//需要发送的帧,结构体设置VCI_CAN_OBJ send[1];send[0].ID=0;send[0].SendType=0;send[0].RemoteFlag=0;send[0].ExternFlag=1;send[0].DataLen=8;int i=0;for(i = 0; i < send[0].DataLen; i++){send[0].Data[i] = i;}int m_run0=1;pthread_t threadid;int ret;ret=pthread_create(&threadid,NULL,receive_func,&m_run0);int times = 5;while(times--){if(VCI_Transmit(VCI_USBCAN2, 0, 0, send, 1) == 1){printf("Index:%04d ",count);count++;printf("CAN1 TX ID:0x%08X",send[0].ID);if(send[0].ExternFlag==0) printf(" Standard ");if(send[0].ExternFlag==1) printf(" Extend ");if(send[0].RemoteFlag==0) printf(" Data ");if(send[0].RemoteFlag==1) printf(" Remote ");printf("DLC:0x%02X",send[0].DataLen);printf(" data:0x");for(i=0;i<send[0].DataLen;i++){printf(" %02X",send[0].Data[i]);}printf("\n");send[0].ID+=1;}else{break;}if(VCI_Transmit(VCI_USBCAN2, 0, 1, send, 1) == 1){printf("Index:%04d ",count);count++;printf("CAN2 TX ID:0x%08X", send[0].ID);if(send[0].ExternFlag==0) printf(" Standard ");if(send[0].ExternFlag==1) printf(" Extend ");if(send[0].RemoteFlag==0) printf(" Data ");if(send[0].RemoteFlag==1) printf(" Remote ");printf("DLC:0x%02X",send[0].DataLen);printf(" data:0x"); for(i = 0; i < send[0].DataLen; i++){printf(" %02X", send[0].Data[i]);}printf("\n");send[0].ID+=1;}else break;}usleep(10000000);//延时单位us,这里设置 10 000 000=10s 10s后关闭接收线程,并退出主程序。m_run0=0;//线程关闭指令。pthread_join(threadid,NULL);//等待线程关闭。usleep(100000);//延时100ms。VCI_ResetCAN(VCI_USBCAN2, 0, 0);//复位CAN1通道。usleep(100000);//延时100ms。VCI_ResetCAN(VCI_USBCAN2, 0, 1);//复位CAN2通道。usleep(100000);//延时100ms。VCI_CloseDevice(VCI_USBCAN2,0);//关闭设备。//除收发函数外,其它的函数调用前后,最好加个毫秒级的延时,即不影响程序的运行,又可以让USBCAN设备有充分的时间处理指令。//goto ext;
}
显示列表说明:
1)第一列 Index 为列表序号:0 开始递增。
2)第二列为通道号:CAN1/CAN2 两通道
3)第三列为帧方向:RX(接收),TX(发送)
4)第四列为 ID
5)第五列为帧格式:Standard(标准帧)、Extend(扩展帧)
6)第六列为帧类型:Data(数据帧)、Remote(远程帧)
7)第七列为帧长度
8)第八列为数据
9)第九列为时间标识:只有接收帧才有。
注意:
1) 运行时,一定要加 Sudo 获取权限运行,否则 USB 设备没有权限操作。
2) 因为发送与接收在两个线程中,线程没有同步。所以在显示时,有可能出现数据错位。
3) 测试程序 10s 内会自动退出,将不会再接收总线上的其它数据
**
USB 权限设置
**
因Linux系统下将涉及到usb底层驱动的调用,运行时,一定要加sudo获取权限运行,否则USB
设备没有权限操作。 现提供一种USB权限设置,配置后,可以不加权限运行。
1、 不加 sudo 权限运行,将会报如下错误:
2、 下面创建一个新的 udev 规则。名称取为:99-myusb.rules
sudo vi /etc/udev/rules.d/99-myusb.rules
注意:
1、 数字 99 最好不要改动,否则可能设置失败
2、 要加 sudo
3、 把以下两行代码复制到新建的 99-myusb.rules 文件中
注意:按键盘上 Insert 键切换到“REPLACE”输入模式
ACTION==“add”,SUBSYSTEMS==“usb”, ATTRS{idVendor}“04d8”, ATTRS{idProduct}“0053”,
GROUP=“users”, MODE=“0777”
4、 按“Esc”键一次
5、 直接输入“:wq”回车,即保存退出
6、 插拔一下 USBCAN 设备或重启一下电脑后,即可不加 sudo 权限运行程序了。
Ubuntu16.04 (ROS)下通过CAN分析仪(USBCAN/CANalyst-II)调试无人车助力转向电机(1)相关推荐
- 在Ubuntu16.04 + ROS kinetic环境下安装TurtleBot3
简介 ROS社区中丰富的功能包和机器人案例为我们的学习和研究提供了绝好的平台.TurtleBot系列是ROS社区中最流行的高性价比机器人平台,前后一共发布了三代. TurtleBot是ROS中最为重要 ...
- Ubuntu16.04 + ROS kinetic + 激光slam-cartographer ROS + 数据仿真 + Turtlebot3仿真
一.Ubuntu16.04 +ROS kinetic的安装及问题解决 https://blog.csdn.net/GGY1102/article/details/107877937 二.Cartogr ...
- 【环境配置】使用 docker 制作一个ubuntu16.04 + ROS + pytorch-gpu 的镜像
文章目录 使用 docker 制作一个ubuntu16.04 + ROS + pytorch-gpu 镜像的过程 1. 我的笔记本环境: 2. 环境配置过程 2.1. 在 ubuntu 16.04 中 ...
- 工作站Ubuntu16.04环境下安装nvidia显卡驱动
近期实验室的工作站,由于teamviewer的原因又崩了.这次只能重装系统才得以解决.nvidia驱动安装步骤记录如下: 备注:工作站品牌为北京联众集群.配备有2块NVIDIA Titan xp 12 ...
- ubuntu16.04系统下谷歌浏览器不能拖入下载好的扩展程序离线包
全地球人都知道,国内无法打开Chrome插件商店. 不过,国内有很多下载站,用户可以自行搜索,下载插件,然后离线安装. 但是,事情出现了变化. 最新版本的Chrome浏览器,主版本号为67,发布日期大 ...
- Ubuntu16.04系统下汉字显示为方框解决办法
Ubuntu16.04系统下汉字显示为方框解决办法 问题详情 打开Ubuntu系统,发现中文变方框了 问题分析 之前中文显示好好的,突然就中文变方框了.原先以为是语言的问题,后面换成了别的中文样式,发 ...
- linux(ubuntu16.04)系统下Matlab2015b软件下载与安装
Linux版Matlab2015b软件下载安装与运行 一.Matlab软件(Linux版)百度网盘下载 二.软件安装教程 三.软件破解步骤 四.打开软件和添加环境变量 五.创建linux桌面快捷方式 ...
- Faster R-CNN python版在Ubuntu16.04环境下配置编译
Faster R-CNN python版在Ubuntu16.04环境下配置编译 1 电脑配置 2 安装显卡驱动 3 安装CUDA 3.1 安装CUDA 3.2 安装CUDNN 3.3 Samples测 ...
- 保姆级教程——Ubuntu16.04 Server下深度学习环境搭建:安装CUDA8.0,cuDNN6.0,Bazel0.5.4,源码编译安装TensorFlow1.4.0(GPU版)...
写在前面 本文叙述了在Ubuntu16.04 Server下安装CUDA8.0,cuDNN6.0以及源码编译安装TensorFlow1.4.0(GPU版)的亲身经历,包括遇到的问题及解决办法,也有一些 ...
- Ubuntu16.04+ROS Kinetic环境下svo编译运行
准备工作: 安装Sophus(这个库是维护的比较好的一个李群和李代数的库) 注: 其实你在运行其他版本的slam系统的时候大概率已经安装过,不过这里面执行一下,无伤大雅,也不会搞乱你的系统. #cat ...
最新文章
- 结队项目——第一次作业
- 和法国的剑桥创业老哥的沟通让我发现了很神奇的点
- stm32f7linux,STM32F7串口5初始化失败
- (十二)深入浅出TCPIP之Nagle算法
- stringbuffer常用方法_第八讲:常用类库API
- Python绘制傅里叶变换、反变换与带通滤波图像
- Electron —— Cannot find module ‘index.js’
- Docker基本管理--docker基本操作、镜像制作方法、私有仓库搭建、端口映射、容器互联、数据卷与数据卷容器
- 年会 炫酷 抽奖小程序
- Quartz定时任务框架(二):Trigger触发器详解
- QT应用编程: 获取系统当前时间以及1970到现在的总秒数
- chartengine 图表的应用流程
- 亚瑟阿伦的三十六个问题。
- R语言-变量命名规则
- ofd转成html,如何把Word或者Excel文档转换为ofd格式?
- 干货精讲!java分布式事务框架
- 修改电脑软件默认安装位置、下载位置
- 汇编工具安装一:MASM32的安装!
- 人民币趣味品--收藏新宠
- 流行的javascript库介绍
热门文章
- 举例说明 频分多址FDMA、时分多址TDMA、码分多址CDMA、空分多址SDMA的异同
- UVALive - 4987 (dp+贪心)
- [javascript]Ex站阅读器
- 做“合规”的数据处理者 | 一文图解《网络数据安全管理条例》
- 愤怒的小鸟AR 版终于正式上架!场景超逼真
- 硬盘位置不可用因格式变RAW而打不开:文件或目录损坏且无法读取/此卷不包含可识别的文件系统等无法访问错误-CHKDSK被中止
- ubuntu设置自动关机
- 打印机有关术语及解释
- 用别的卡也显示腾讯免流量服务器,央媒点明腾讯大王卡定向免流套路,网友:防不胜防!...
- 订单下单成功后如何等待支付成功