├── COS495-Lecture5-Odometry.pdf ├── README.md ├── Ros_by_example_indigo_volume_1.pdf ├── gogorobot ├── CS226B-04-MotionAndSensing.pptx └── Hellstrom-ForwardKinematics.pdf ├── init.md ├── mbed培训171013_张宇翔.pdf ├── ros-param-tutorial.md ├── ros-teleop.md ├── ros_by_example_vol_2_indigo.pdf ├── rosserial_rosnode_stm32.md ├── rosserial_stm32.md ├── 基于ROS架构的智能小车 (一)介绍.md ├── 基于ROS架构的智能小车 (七)遥控.md ├── 基于ROS架构的智能小车 (三)底盘的选取.md ├── 基于ROS架构的智能小车 (二)底层开发环境.md ├── 基于ROS架构的智能小车 (五)PID控制.md ├── 基于ROS架构的智能小车 (八)ros基础.md ├── 基于ROS架构的智能小车 (六)PID算法参数调节.md ├── 基于ROS架构的智能小车 (四)编码器.md ├── 执行器电路板讲义.pdf ├── 激光雷达 ├── ROS.zip ├── Ros │ ├── YDLIDAR ROS.pdf │ └── ydlidar_v1.3.1.zip ├── SDK.zip ├── 工具.zip ├── 激光雷达 X4 使用手册.pdf ├── 激光雷达 X4 开发手册.pdf └── 激光雷达 X4 数据手册.pdf ├── 物联机械臂V2.pdf ├── 物联车V2.pdf └── 电机pwm拟合.xlsx /COS495-Lecture5-Odometry.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianyma/ros-stm32-tutorials/22c5f40c06b5a49d526b7760b7b1fcd20198f842/COS495-Lecture5-Odometry.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ros-stm32 2 | -------------------------------------------------------------------------------- /Ros_by_example_indigo_volume_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianyma/ros-stm32-tutorials/22c5f40c06b5a49d526b7760b7b1fcd20198f842/Ros_by_example_indigo_volume_1.pdf -------------------------------------------------------------------------------- /gogorobot/CS226B-04-MotionAndSensing.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianyma/ros-stm32-tutorials/22c5f40c06b5a49d526b7760b7b1fcd20198f842/gogorobot/CS226B-04-MotionAndSensing.pptx -------------------------------------------------------------------------------- /gogorobot/Hellstrom-ForwardKinematics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianyma/ros-stm32-tutorials/22c5f40c06b5a49d526b7760b7b1fcd20198f842/gogorobot/Hellstrom-ForwardKinematics.pdf -------------------------------------------------------------------------------- /init.md: -------------------------------------------------------------------------------- 1 | #### 基于ubuntu16.04和ros下的rikirobot开发环境搭建问题 2 | 3 | - 删除joystick_drivers 4 | - 删除openni_camera 5 | - sudo apt install ros-kinetic-navigation 6 | - sudo apt install ros-kinetic-rosserial 7 | -------------------------------------------------------------------------------- /mbed培训171013_张宇翔.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianyma/ros-stm32-tutorials/22c5f40c06b5a49d526b7760b7b1fcd20198f842/mbed培训171013_张宇翔.pdf -------------------------------------------------------------------------------- /ros-param-tutorial.md: -------------------------------------------------------------------------------- 1 | https://blog.csdn.net/wengge987/article/details/50620121 -------------------------------------------------------------------------------- /ros-teleop.md: -------------------------------------------------------------------------------- 1 | https://blog.csdn.net/hcx25909/article/details/9004617 2 | -------------------------------------------------------------------------------- /ros_by_example_vol_2_indigo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianyma/ros-stm32-tutorials/22c5f40c06b5a49d526b7760b7b1fcd20198f842/ros_by_example_vol_2_indigo.pdf -------------------------------------------------------------------------------- /rosserial_rosnode_stm32.md: -------------------------------------------------------------------------------- 1 | # ros 和 stm32 之间的节点通讯 2 | 3 | ### stm32底层 4 | 5 | - stm32底层代码采用mbed示例代码 6 | 7 | ```c++ 8 | #include "mbed.h" 9 | #include 10 | #include 11 | 12 | ros::NodeHandle nh; 13 | DigitalOut myled(PC_13); 14 | 15 | void messageCb(const std_msgs::String& toggle_msg){ 16 | myled = !myled; // blink the led 17 | } 18 | // 建立接收节点 19 | ros::Subscriber sub("toggle_led", &messageCb); 20 | 21 | int main() { 22 | nh.initNode(); 23 | //订阅 24 | nh.subscribe(sub); 25 | 26 | while (1) { 27 | nh.spinOnce(); 28 | wait_ms(1); 29 | } 30 | } 31 | ``` 32 | 33 | 34 | 因为采用节点通讯,所以在stm32端和ros端都要有相应的节点建立同样的topic,不能用ASIO串口通讯库 35 | 36 | - ros 37 | 38 | 发布节点代码: 39 | ```c++ 40 | /*发送和接收节点的msg类型必须相同,这里都std_msg/String*/ 41 | #include "ros/ros.h" 42 | #include 43 | #include 44 | #include 45 | int main(int argc,char **argv) 46 | { 47 | ros::init(argc,argv,"talker"); 48 | ros::NodeHandle n; 49 | ros::Publisher chatter_pub=n.advertise("toggle_led",1000);//发布节点 50 | ros::Rate loop_rate(0.5);//0.5Hz发送消息 51 | 52 | while(ros::ok()) 53 | { 54 | std_msgs::String msg; 55 | std::stringstream ss; 56 | ss<<"toogle_led"; 57 | msg.data=ss.str(); 58 | ROS_INFO("%s",msg.data.c_str());//打印发送消息 59 | chatter_pub.publish(msg); 60 | ros::spinOnce(); 61 | loop_rate.sleep(); 62 | } 63 | return 0; 64 | } 65 | ``` 66 | 不要忘记改节点下的CMakeList.txt文件 67 | 68 | ---------------- 69 | ##advanced: 在stm32端解析收到的message 70 | - 有几个必须要注意的坑 71 | 1.正确理解rostopic,在任意**一对**publisher和subscriber中,必须要有**相同的topic和message类型**才能进行二者的通讯,例如 72 | ```c++ 73 | ros::Publisher chatter_pub=n.advertise("talker",1000); 74 | ros::Subscriber sub("talker", &messageCb); 75 | ``` 76 | 在pub函数中,第一个参数是topic,第二个参数是数据长度(以字节记) 77 | 在sub函数中,第一个参数是topic,第二个参数是回调函数,回调函数就是,接收到数据后stm32将要执行的工作,例如 78 | ```c++ 79 | void messageCb(const std_msgs::String &toggle_msg){ 80 | myled = !myled; // blink the led 81 | pc.printf("message:%s\n",toggle_msg.data); 82 | } 83 | ``` 84 | 回调函数的参数是收到的message,如果要读取message的data,则使用msg.data读取,示例中是在串口中打印message。 85 | **要特别注意在stm32和ros上写subscriber节点的区别,两者使用的库虽然都是kinetic,但函数还是有一定区别,所以要区别开** 86 | ####最后,看一下在ros端的publisher节点和stm32端的subscirber节点的完整代码,这里模拟发送限速度和角速度,然后在stm32解析出来并在串口打印 87 | publisher: 88 | ```c++ 89 | #include 90 | #include "ros/ros.h" 91 | #include 92 | #include 93 | #include 94 | 95 | int main(int argc,char **argv) 96 | { 97 | ros::init(argc,argv,"talker"); 98 | ros::NodeHandle n; 99 | int a,b,c,d,e,f,sum; 100 | a=b=c=d=e=f=2; 101 | sum=a+b+c+d+e+f; 102 | ros::Publisher chatter_pub=n.advertise("talker",1000); 103 | ros::Rate loop_rate(0.5); 104 | 105 | while(ros::ok()) 106 | { 107 | std_msgs::String msg; 108 | std::stringstream ss; 109 | ss<<"S W "< 127 | #include 128 | 129 | std_msgs::String str_msg; 130 | ros::Publisher chatter("chatter", &str_msg); 131 | 132 | DigitalOut myled(PC_13); 133 | Serial pc(PA_9,PA_10,9600); 134 | 135 | char a,b,c,d,e,f,sum; 136 | void messageCb(const std_msgs::String &toggle_msg){ 137 | myled = !myled; // blink the led 138 | pc.printf("message:%s\n",toggle_msg.data); 139 | 140 | } 141 | std_msgs::String receivemessage; 142 | ros::Subscriber sub("talker", &messageCb); 143 | int main() { 144 | ros::NodeHandle nh; 145 | nh.initNode(); 146 | nh.subscribe(sub); 147 | while (1) { 148 | nh.spinOnce(); 149 | wait_ms(1000); 150 | } 151 | } 152 | ``` 153 | 注意这两种打印方式的区别 154 | ```c++ 155 | //串口打印,在stm32端读取使用message的内容 156 | pc.printf("message:%s\n",toggle_msg.data); 157 | //ROS打印 158 | ROS_INFO("%s",msg.data.c_str()); 159 | ``` 160 | ---------------------------- 161 | 另外,要注意rosserial_python默认的发送波特率是57600,stm32接收的波特率也是57600。如果要从串口测验读取message,则需要在新的引脚(PA_9,PA_10)读取,因为ros和stm32通讯占用了(PA_2,PA_3),并把波特率设置成其他,这里是选择了9600。串口调试工具我在ubuntu用cutecom,windos不太清楚请自查。 162 | 参考网址: 163 | http://www.360doc.com/content/16/0820/12/7821691_584529013.shtml 164 | https://www.cnblogs.com/xuanxiaochen/p/6013886.html 165 | 166 | -------------------------------------------------------------------------------- /rosserial_stm32.md: -------------------------------------------------------------------------------- 1 | #ros与stm32串口通讯操作方法 2 | 3 | --------------------- 4 | 5 | - 利用mbed在stm32上烧写好串口通讯的程序 6 | 7 | ```c++ 8 | #include "mbed.h" 9 | 10 | //------------------------------------ 11 | // Hyperterminal configuration 12 | // 9600 bauds, 8-bit data, no parity 13 | //------------------------------------ 14 | 15 | Serial pc(PA_2, PA_3); 16 | 17 | int main() 18 | { 19 | while(1) 20 | { 21 | pc.printf("rikirobot"); 22 | wait(1); 23 | } 24 | } 25 | 26 | 27 | ``` 28 | 29 | - 连接到ros上,注意可能需要修改设备的权限 30 | ``` 31 | sudo chmod 777 /dev/ttyUSB0 32 | ``` 33 | 或者永久修改权限 34 | ``` 35 | sudo usermod -aG dialout ${当前用户名} 36 | ``` 37 | - 在已有的ros package的src目录下写一个message收发的节点,以boost_node.cpp为例 38 | 39 | ``` 40 | $ cd ~/catkin_ws/src/rikirobot_project/rikirobot/src 41 | $ sudo vi boost_node.cpp 42 | ``` 43 | 44 | ```c++ 45 | #include 46 | #include 47 | #include "std_msgs/String.h" 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | 54 | using namespace std; 55 | using namespace boost::asio; 56 | 57 | int main(int argc, char* argv[]) 58 | { 59 | ros::init(argc,argv,"boost"); 60 | ros::NodeHandle n; 61 | ros::Rate loop_rate(0.5); 62 | io_service iosev; 63 | ros::Publisher chatter_pub = n.advertise("chatter",1000); 64 | 65 | //节点文件 66 | serial_port sp(iosev, "/dev/ttyUSB0"); 67 | // 设置参数 68 | sp.set_option(serial_port::baud_rate(9600)); 69 | sp.set_option(serial_port::flow_control(serial_port::flow_control::none)); 70 | sp.set_option(serial_port::parity(serial_port::parity::none)); 71 | sp.set_option(serial_port::stop_bits(serial_port::stop_bits::one)); 72 | sp.set_option(serial_port::character_size(8)); 73 | // 向串口读数据 74 | char bufstart[13]; 75 | read(sp,buffer(bufstart)); 76 | printf("%s\n",bufstart); 77 | while(ros::ok()) 78 | { 79 | 80 | read(sp, buffer(buf)); 81 | printf("buf= %s\n",buf); 82 | ros::spinOnce(); 83 | loop_rate.sleep(); 84 | } 85 | iosev.run(); 86 | return 0; 87 | } 88 | 89 | ``` 90 | 91 | 92 | 93 | - 编写完成后,需要修改CMakelist 94 | 95 | ``` 96 | $ cd ~/catkin_ws/src/rikirobot_project/rikirobot/ 97 | $ sudo vi CMakelist.txt 98 | ``` 99 | 100 | 在最后添加如下代码 101 | 102 | ``` 103 | add_executable(boost_node src/boost_node.cpp) 104 | target_link_libraries(boost_node ${catkin_LIBRARIES}) 105 | ``` 106 | 107 | 保存 108 | 109 | ``` 110 | $ cd ~/catkin_ws 111 | $ catkin_make 112 | ``` 113 | 114 | -编译如果失败可能没有获取设备最高权限 115 | - 编译成功后 116 | 117 | ``` 118 | $ rosrun rikirobot boost_node.cpp 119 | ``` 120 | 121 | 122 | 就可以看到串口传输过来的数据,可以读写,如果数据格式有问题,可以去源码修正 123 | #### 参考网址 124 | 125 | - https://blog.csdn.net/u010925447/article/details/58042702 126 | - https://www.cnblogs.com/li-yao7758258/p/5794005.html 127 | -------------------------------------------------------------------------------- /基于ROS架构的智能小车 (一)介绍.md: -------------------------------------------------------------------------------- 1 | # 基于ROS架构的智能小车 (一)介绍 2 | 3 | #### 引:这个例程是我在准备robot-IDC时的学习笔记,结合之前学习ros的一些体会,和参加RoboCup时Tinker的设计思路做的一些自己的总结,希望对对ROS和机器人感兴趣的童鞋一些帮助。 4 | 5 | ** 6 | What is ROS? 7 | The Robot Operating System (ROS) is a set of software libraries and tools that help you build robot applications. From drivers to state-of-the-art algorithms, and with powerful developer tools, ROS has what you need for your next robotics project. And it's all open source.(引自ROS官网) 8 | ** 9 | 10 | ROS是一个基于节点设计的开源机器人操作系统架构,关于ROS的介绍和Tutorial等等可以在官网[http://www.ros.org](http://www.ros.org "www.ros.org")上找到,推荐大家在学习tutorial的时候能够手边有个实体的小车进行练习可以加深理解。 11 | 12 | ----------------------------------- 13 | 如果要对ROS达到一个比较好的理解,除了在软件方面要懂**C/C++或者python编程**,了解ROS库函数,在硬件方面也要有比较充足的了解,比如知道底层驱动控制的方法,理解当前主流的单片机**(stm32/arduino)**的工作方式,理解底层的编程环境,并有一些调试底层bug的经验。这样当我们逐步架构到上位机进行软件开发的时候就可以游刃有余了,到那个时候,我们就可以把底层只当作一个节点,和其他诸如机械臂,雷达的部分一样都是平行的节点,他们统一通过主节点(树莓派上的Master)进行通讯。 14 | > 但是,对于ros的学习,我认为如果对于底层的硬件部分的开发没有经验的话,直接上手去学ROS Tutorial可能有点云里雾里,学过之后也不会有多少印象,反而可能更加失去学习的动力,相反呢,知道了硬件开发,就自然会理解ROS的思想,从而提高我们的学习效率和理解。 15 | 16 | #### 正如梁老师讲的,机器人的开发最重要的是分层设计的思想,一步步进行学习和封装,就会使我们的机器人功能逐渐增多而不显得杂乱无章。在这个例程里面,我首先会讲解如何一步一步做一个纯stm32底层单片机控制的遥控小车,然后再讲解ros的架构以及如何用ros的节点机制来进行键盘控制和自动导航,最后可能会加上各种各样的传感器,甚至是机械臂,组成一个类似于Tinker的家庭服务机器人。 17 | 18 | 那就让我们开始底层硬件部分的学习吧。 19 | 20 | 21 | -------------------------------------------------------------------------------- /基于ROS架构的智能小车 (七)遥控.md: -------------------------------------------------------------------------------- 1 | # 基于ROS架构的智能小车 (七)遥控 2 | 3 | 小车的遥控涉及到stm32的中断处理,王若溪学长写了相关的代码直接用就可以了。 4 | 5 | 我们用的是futaba 6-channel 2.4GHz Computer Radio System遥控器 6 | 7 | ![](https://i.imgur.com/yuiyTCA.jpg) 8 | 9 | ![](https://i.imgur.com/SJbg0tp.png) 10 | 11 | 资料貌似只有英文的,所以还是看说明书吧。简单介绍一下,一共有六个通道可以进行控制,小车的运动只涉及两个通道(前后,左右)。 12 | 13 | 直接在main中的中断中可以获得tim3IC1Width, tim3IC2Width, tim3IC3Width, tim3IC4Width, tim1IC2Width, tim1IC3Width六个通道的值,通过和电机的转速进行换算就可以进行控制了。 14 | 15 | 例如 16 | ```c++ 17 | 18 | auto2wheel my_auto; 19 | Ticker toggle_time_ticker; 20 | 21 | void time_ticker(){//中断 22 | // Tim3_ser1.printf(" %d %d\n",tim3IC3Width, tim3IC4Width);//使用tim3的通道3和通道4,值的范围是1100-1950. 23 | if((12001800) 28 | { 29 | my_auto.spin(-tim3IC3Width+1450); 30 | } 31 | if(tim3IC4Width<1200||tim3IC4Width>1800) 32 | { 33 | my_auto.mv_x(-tim3IC4Width+1450,-tim3IC4Width+1450); 34 | } 35 | } 36 | int main() 37 | { 38 | //controler init 39 | HAL_Init(); 40 | TIM1_3_Config(); 41 | toggle_time_ticker.attach(&time_ticker, 0.2); 42 | } 43 | 44 | ``` 45 | 46 | 到此阶段,底层硬件的学习就告一段落了。接下来就开始激动人心的ROS学习了,我们需要充分理解节点这一概念进行小车控制的整体设计,开始学习吧。 -------------------------------------------------------------------------------- /基于ROS架构的智能小车 (三)底盘的选取.md: -------------------------------------------------------------------------------- 1 | # 基于ROS架构的智能小车 (三)底盘的选取 2 | 3 | ## 1. 底盘选择 4 | 5 | 底盘的机械部分可以选择两轮驱动差速控制的,也有三个全向轮的,或者四驱的麦克纳姆轮等(Tinker就是四驱的麦克纳姆轮),每一种底盘都有自己的底盘坐标系和轮速之间的对应的转换关系和运动学模型。需要了解清楚。 6 | 7 | ### 两轮差速驱动运动学模型 8 | 9 | - [https://blog.csdn.net/qq_16149777/article/details/73224070](https://blog.csdn.net/qq_16149777/article/details/73224070) 10 | 11 | - [https://robotics.stackexchange.com/questions/106/what-is-a-suitable-model-for-two-wheeled-robots/134#134](https://robotics.stackexchange.com/questions/106/what-is-a-suitable-model-for-two-wheeled-robots/134#134) 12 | 13 | ### 全向轮驱动运动学模型 14 | 15 | - [https://blog.csdn.net/jyaxp/article/details/55050393](https://blog.csdn.net/jyaxp/article/details/55050393) 16 | 17 | 18 | ### 四驱麦克纳姆轮运动学模型 19 | 20 | - [https://www.bilibili.com/video/av17229132/](https://www.bilibili.com/video/av17229132/) 21 | 22 | ## 2.封装的运动学模型库参考 23 | 24 | 可以参考我封装的全向轮和四驱麦克纳姆轮的封装, 25 | 26 | - 全向轮 27 | 28 | > [https://os.mbed.com/users/himarsmty/code/omni/](https://os.mbed.com/users/himarsmty/code/omni/) 29 | 30 | 其中使用到的QEI的库是编码器的库,可以先不用管,直接看Motor_3和omni就好。 31 | 32 | - 四驱麦克纳姆轮 33 | 34 | > [https://os.mbed.com/users/himarsmty/code/mecanum_4/](https://os.mbed.com/users/himarsmty/code/mecanum_4/) 35 | 36 | ------------------------- 37 | 38 | **我们这里以最简单的两轮差分模型来进行学习,在结合ros的时候可以降低理解的难度,但要先理解了两轮驱动的运动学模型。** -------------------------------------------------------------------------------- /基于ROS架构的智能小车 (二)底层开发环境.md: -------------------------------------------------------------------------------- 1 | # 基于ROS架构的智能小车 (二)底层开发环境 2 | 3 | - stm32单片机 4 | 5 | 首先选取底层的驱动的单片机,市场上的单片机五花八门,以降低开发环境的复杂度为原则,我们选择的是**STM32F103C8T6**,(其实我当时在想为什么不用arduion,不过后来感觉还是stm32更好用一点)结合Mbed的在线开发环境开发,用的电路板是梁老师的C8T6的最小系统开发板。 6 | 7 | >关于最小系统开发板的介绍,参见**梁老师的执行器电路板讲义.pdf**。 8 | 9 | - Mbed在线开发环境 10 | Mbed的开发环境的优点在于开发过程简洁,其编译器是C++编译器,而且Mbed.h的库已经封装了绝大多数我们需要的stm32功能,所以只要懂C++编程就可以上手了。将stm32单片机通过st-link连接到电脑上,(注意是有一种紫色的st-link,好像是v2版,主机是可以把它当作USB来识别的),在线编译后将生成的.bin,直接下载到单片机上,看到st-link的指示灯闪三次(在firefox上下载)或者两次(在chrome上下载),就表明已经烧写到了单片机中了,这比keil方便很多。但有时侯连续使用时间过长就可能烧写失败,这种情况的话重新拔插一下st-link就好了。 11 | 12 | > 初次接触Mbed的话,可以参考张宇翔学长的**mbed培训171013.pdf**,参考做几个学长给的几个例程就会熟悉了,用起来还是非常方便的。 13 | 14 | 最后对照C8T6最小系统电路板的电路图,查看对应的引脚,将stm32插入到电路板上(注意方向)就可以进行控制了。 15 | 16 | - 电机驱动 17 | 电机驱动板使用的是L298N直流电机驱动板。 18 | 19 | ![](https://i.imgur.com/jNydTpr.png) 20 | 21 | 可以通过输出A和输出B同时驱动两个电机,以一个电机的控制为例子,有两种可以选择的控制方式,一种是两输出的,即两个输出口都是Pwm输出,通过脉宽相对大小控制转向和转速,一般是如果正转的话,一个为0,另一个调节脉宽来调节转速,反转相反。见下图 22 | 23 | ![](https://i.imgur.com/4jbahqX.png) 24 | 25 | 另一种则是需要拔出通道使能的短路片,将中间的逻辑输入的两个引脚作为DigitalOut的GPIO口,通过高低电平控制转向,然后让边上的口作为pwm输出调节转速,边上pwm输出前面的引脚是板载5V使能,可以不用管。 26 | 27 | > 对应的单片机引脚参照**梁老师的执行器电路板讲义.pdf**中的**Mbed 环境下 STM32F103C8T6 管脚资源表**。 28 | 29 | 例程的话我封装了两输出[Motor_2](https://os.mbed.com/users/himarsmty/code/motor_2/ "Motor_2的库")的库,可以参考自己写出三输出的库。 30 | 31 | > 关于L298N驱动板的介绍,也可以参考[https://www.ncnynl.com/archives/201612/1204.html](https://www.ncnynl.com/archives/201612/1204.html "搭建ROS小车底盘-第一篇硬件") 32 | 33 | --------------------------------- 34 | 35 | 到此为止,我们的底层的开发环境就基本搭建完成了,底层开发调试的话通过串口打印Serial类调试是很有帮助的,也可以学习一下。下一步,我们讲底盘的选择和控制。 -------------------------------------------------------------------------------- /基于ROS架构的智能小车 (五)PID控制.md: -------------------------------------------------------------------------------- 1 | # 基于ROS架构的智能小车 (五)PID控制 2 | 3 | 获取了编码器的速度后,就可以通过PID进行闭环控制了,从而让我们的小车可以以精确的速度进行移动了。这尤其在三轮全向轮的控制这种轮速对底盘运动方向影响很明显的情况有帮助。 4 | 5 | ### PID算法(比例-积分-微分) 6 | 7 | 可以参考以下博客: 8 | - [https://www.cnblogs.com/cv-pr/p/4785195.html](https://www.cnblogs.com/cv-pr/p/4785195.html) 9 | - [http://blog.gkong.com/liaochangchu_117560.ashx](http://blog.gkong.com/liaochangchu_117560.ashx) 10 | 11 | 算法代码可以参考我写的一个简单的pid,可以自己进行一些模拟输入加深理解。 12 | 13 | ```c++ 14 | #ifndef PID_MTY_H_ 15 | #define PID_MTY_H_ 16 | typedef struct PID_tag{ 17 | double setPoint;//desired value 18 | double P;//proportion 19 | double I;//Integral 20 | double D;//Dervative 21 | double LastError; 22 | double PrevError; 23 | double SumError; 24 | }PID; 25 | 26 | 27 | double compute(PID *pid_contorler,double NextPoint) 28 | { 29 | double dError,Error; 30 | Error=pid_contorler->setPoint-NextPoint;//设定值-采样值 31 | pid_contorler->SumError+=Error;//积分 32 | dError=pid_contorler->LastError-pid_contorler->PrevError;//微分,偏差相减 33 | pid_contorler->PrevError=pid_contorler->LastError; 34 | pid_contorler->LastError=Error; 35 | double speed=pid_contorler->P*Error+pid_contorler->I*pid_contorler->SumError+pid_contorler->D*dError;//delta speed 36 | return speed;//比例项+积分项+微分项 37 | } 38 | //double sensor() 39 | //{ 40 | // return 100.0; 41 | //} 42 | #endif 43 | //int main() 44 | //{ 45 | // PID my_pid; 46 | // double rout; 47 | // double rin; 48 | // my_pid.P=0.5; 49 | // my_pid.I=0,5; 50 | // my_pid.D=0.0; 51 | // my_pid.setPoint=(100.0); 52 | // while(1) 53 | // { 54 | // rin=sensor(); 55 | // rout=compute(&my_pid,rin); 56 | // cout<