利用绝对值编码器计算odom&阿克曼运动学模型

您所在的位置:网站首页 阿克曼模型计算 利用绝对值编码器计算odom&阿克曼运动学模型

利用绝对值编码器计算odom&阿克曼运动学模型

2023-09-27 03:06| 来源: 网络整理| 查看: 265

一、绝对值编码器:增量编码器有一个缺点:即当发生电源故障时丢失轴位置。然而,对于绝对编码器来说,即使发生电源故障也不丢失轴位置。绝对编码器由机械位置确定编码,它无需记忆,无需找参考点,而且不用一直计数,什么时候需要知道位置,什么时候就去读取它的位置。这样,编码器的抗干扰特性、数据的可靠性大大提高了。

二、编码器参数:64圈绝对值编码器;12位(4096)即一圈4096个脉冲;Modbus RTU协议。38mm外径/6mm轴。

三、Modbus RTU协议:当通讯命令由发送设备(主机)发送至接收设备(从机)时,符合相应地址码的从机(编码器)接收通讯命令,并根据功能码及相关要求读取信息,如果CRC校验无误,则执行相应的任务,然后把执行结果(数据)返送给主机。返回的信息中包括地址码、功能码、执行后的数据以及CRC校验码。如果CRC校验出错就不返回任何信息。此编码器支持 03H/06H/10H 功能码,分别是读取编码器数据、修改站号、设置原点。 在这里插入图片描述四、计算里程: 编码器值 = 圈数单圈分辨率 + 单圈值。 例如圈数 10 位 1024 圈,单圈 12 位 4096P 编码器。编码器值 = 圈数4096 + 单圈值。 角度转换方法:单圈 0x01D7 转 10 进制为 471,圈数 0x0209 转 10 进制共 521 圈。 单圈角度 = (471/ 1024) * 360° = 165.59° 总角度 = 圈数*360 + 单圈角度

五、串口读取与解析(源码):

#include "ros/ros.h" #include "serial/serial.h" #include "std_msgs/String.h" #include "std_msgs/UInt8.h" #include "std_msgs/UInt8MultiArray.h" #include "encode/mobileRobot_msgs.h" #include "std_msgs/UInt8MultiArray.h" #include "std_msgs/MultiArrayDimension.h" #include "string.h" #include #include //ros::Publisher read_pub; ros::Publisher odom_pub; serial::Serial ser; int main (int argc, char** argv) { // initial parameters std::string node_name; static uint8_t lcmd_buffer[8]={0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B}; //static uint8_t reset[8]={0x01, 0x06, 0x00, 0x02, 0x00, 0x02, 0xA9, 0xCB}; uint8_t serial_data[9]; float d=0.36;//轮子直径 float pai=3.1415925; // initial parameter service ros::init(argc, argv, "encode_node"); node_name=ros::this_node::getName(); ROS_INFO("%s is starting...", node_name.c_str()); ros::NodeHandle nh; tf::TransformBroadcaster odom_broadcaster; odom_pub = nh.advertise("my_odom", 5); try { ser.setPort("/dev/ttyUSB0"); ser.setBaudrate(9600); serial::Timeout to = serial::Timeout::simpleTimeout(1000); ser.setTimeout(to); ser.open(); } catch (serial::IOException& e) { ROS_ERROR_STREAM("Unable to open port "); return -1; } if(ser.isOpen()) { ROS_INFO_STREAM("Serial Port opened"); } else { return -1; } ros::Time current_time, last_time; current_time = ros::Time::now(); last_time = ros::Time::now(); ros::Rate loop_rate(50); while(ros::ok()) {ser.write(lcmd_buffer,8); //ROS_INFO_STREAM("Write to serial port"); //获取缓冲区的字节数 size_t n = ser.available(); bool ifread=false; bool ifhead=false; int count=0; if (n!=0) { uint8_t buffer[1024]; //读取数据 n = ser.read(buffer , n); for (int i=0; i if(buffer[i]==0x03) { ifread=true; count=1; } ifhead=false; } if (buffer[i]==0x01) { ifhead=true; } if (ifread) { serial_data[count]=buffer[i]; count++; // std::cout //m.data[0]=0x01; //m.data[j]=serial_data[j]; serial_data[0]=0x01; int Single_cycle_pulse=int(serial_data[3]*256+serial_data[4]); int cycle_number=int(serial_data[5]*256+serial_data[6]); float Total_angle=(Single_cycle_pulse/4096)*360+cycle_number*360; //std::cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3