利用绝对值编码器计算odom&阿克曼运动学模型 |
您所在的位置:网站首页 › 阿克曼模型计算 › 利用绝对值编码器计算odom&阿克曼运动学模型 |
一、绝对值编码器:增量编码器有一个缺点:即当发生电源故障时丢失轴位置。然而,对于绝对编码器来说,即使发生电源故障也不丢失轴位置。绝对编码器由机械位置确定编码,它无需记忆,无需找参考点,而且不用一直计数,什么时候需要知道位置,什么时候就去读取它的位置。这样,编码器的抗干扰特性、数据的可靠性大大提高了。 二、编码器参数:64圈绝对值编码器;12位(4096)即一圈4096个脉冲;Modbus RTU协议。38mm外径/6mm轴。 三、Modbus RTU协议:当通讯命令由发送设备(主机)发送至接收设备(从机)时,符合相应地址码的从机(编码器)接收通讯命令,并根据功能码及相关要求读取信息,如果CRC校验无误,则执行相应的任务,然后把执行结果(数据)返送给主机。返回的信息中包括地址码、功能码、执行后的数据以及CRC校验码。如果CRC校验出错就不返回任何信息。此编码器支持 03H/06H/10H 功能码,分别是读取编码器数据、修改站号、设置原点。 五、串口读取与解析(源码): #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 |