The Limitations of Classical PID Controller and Its Advanced Derivations

Since founded by N. Weiner in 1947, the control theory has been evolved for more than 60 years and is still full of challenges and opportunities. The most important principle of the control theory, in my opinion, is the feedback mechanism. Without feedback and closed-loop, almost no algorithm and control technique can be implied. The idea of feedback is that by comparing the reference input and the actual output, an error signal can be obtained and then can be used by the controller to trace and eliminate the difference between the input and the output. Apart from Watt’s steam engine, one could say that the first formally implication of (negative) feedback is the amplifier invented by H.S. Black. It is a genius idea when first came out in 1927 and was proved to be an extremely useful way to solve electronic and control problems. The idea of output feedback has also been extended to state feedback and error feedback to achieve state control and estimation in more advanced control techniques.

Classical control is the foundation of control theory and it is more concentrated on analysing the stability and performance of a controlled plant. However, only linear and SISO systems have been discussed in classical control theory. Although traditional control techniques such as PID controller are still widely used in industry, they cannot handle more complex engineering scenarios such as aerospace, chemistry and biology. Another problem of classical control is that all parameters are designed and tuned based on the current system model, in which case the system will be more vulnerable to further disturbance and parameters varying.

In order to solve these problems of classical PID controller which mentioned before, more advanced approaches have been derived nowadays. If using classical approach to control a MIMO system, one should divide the system into different modes and control each mode separately. However if the system inputs and outputs are coupled with each other, it cannot be decoupled and this method will not be practicable anymore. Here comes the state-space method, which solved the limitation of classical control by using state variables. The advantage of state-space is that it can be represented by matrices and such is very computer-friendly. State-space representation is actually defined in time domain instead of frequency domain and every state can have some extend of physical meaning which gives some clues about what is happening inside a controlled plant. One milestone which makes the state-space method more practicable is the invention of Kalman filter. Kalman filter uses a series of history measurements in the presence of noise to estimate the current state of the system. Kalman filter can work as a state estimator or simply a special filter which uses the physical system model to remove the process and the measurement noise.

Optimal control method such as MPC and LQR is another derivation of classical control. In most circumstances, there are more than one possible control inputs which can drive the system to work properly, but we need is to find the optimal one. Optimal control actually transforms the control problem into an optimal problem which tries to minimise an objective function to get the best outcome. Another advantage of optimal control is that it can take constraints into consideration. One defect of PID controller is that it cannot handle system constraints like actuator saturation or output limitation. In the optimal case control, design a controller with constraints could be feasible.

It is also known that no system is constant and some parameters are likely to vary with time or to the working condition. In classical control, the controller is designed just for the current system model and thus may loss performance or even be unstable due to the system change and uncertainties. In such aspect, adaptive control or robust control may be more applicable. Both adaptive control and robust control are designed to cope with uncertainties. The difference is that adaptive control identifies the system model and changes its parameters in real-time, but robust control fixed its parameters after deployed to the plant. For the truth that adaptive control has to calculate the system model every few periods, it needs much more computational time. What’s more, since the control parameters in the adaptive controller are changing every time, it may be difficult to prove its stability.  On the other hand, the gain of robust controller has already been designed before applied to the system, so it doesn’t need to do additional calculation during the operation. Since robust controller is globally optimised and especially designed to handle uncertainties, it may not have a performance as good as other controllers. But since the real control problems are always not ideal, it is meaningful to take uncertainties and disturbance into the system model.

Some more advanced control techniques such as neural network and expert control are being discussed today. In my opinion, these new approaches have the potential to be the next generation of control theory. With the developing of computer science, it is now possible to model extremely complex networks. This kind of controller can actually take all the possible system states and its corresponding solutions into a database and each time just search for the best solution according to the current system data.  New techniques such as machine learning can also be absorbed into the controller and make the controller more flexible which can handle different control problems using a same configuration.

However, no matter how powerful the control method is, there are rarely situations where we do not need to make trade-offs. As human-beings, we always need to make decisions and balance the income and the expense. Being too greedy is like giving an infinite gain to a helicopter, which may work at the beginning but will suddenly crash whenever there is any disturbance. So push yourself while keep in mind that you have limitation. Take it easy, be adaptive to the environment and always try to get the optimal solution of your life.


[1] R.C. Dorf & R.H. Bishop, Modern Control Systems (Twelfth Edition), Pearson, USA.

[2] Wikipedia, Harold Stephen Black. Available at: Last accessed 26th Mar 2014

[3] E.F. Camacho and C. Bordons, Modern Predictive Control, Springer, London, 2003


1. 引子


  • 直接和GPIO插口对接的屏幕,使用SPI与CPU进行通信。需要特殊的驱动程序将framebuffer的内容发送到LCD控制器上,一般带有触屏功能,大小以3.5寸为主流。受限于SPI通信速度,刷新速率不高;
  • 专用USB接口的屏幕,如RoboPeak Mini USB Display。这类屏幕通过USB连接,需要本地运行驱动程序;
  • 通用LCD屏幕,通过HDMI和树莓派连接。因其通用性不需要特殊的驱动程序,但是很多都不支持触屏功能,而且都需要额外的转接板,体积较大;

▲ 图.  树莓派官方7寸屏实拍


  • 官方屏的LCD模组最有保证,淘宝上的HDMI LCD一般成像质量不高;
  • 官方屏的触摸功能在所有方案中是支持的最好的,有十点电容触摸(目前Raspbian还只支持单点,以后会升级),且不需要额外驱动。而HDMI接口的LCD如果有触摸功能,都需要额外接一根USB用于提供触摸控制;
  • 官方触屏和树莓派3可以直接通过铜柱物理连接,无需额外的驱动电路板。连线也非常少,只需要一根DSI软排线和供电接口即可。

▲ 图. 树莓派官方LCD屏实拍 – 正面

Read more »


目前主流的C/C++命名风格有两种:一种是Windows风格的匈牙利命名法,主要是采用类型前缀 + 变量名首字母大写,另一个就是Unix/Linux命名习惯。我自己采用的是基于Unix的变种,融合了匈牙利命名法的一些优点,在这里分享给大家。

变量名的组成:(模块名) +  (作用域) + (类型前缀) + 变量名 + (变量名后缀),解释如下:

  • 变量名 以小写的英文字母构成,词与词之间用下划线连接,如key_value, data_src; 不可使用数字,不混用大小写;
  • 模块名 声明该变量属于的模块,防止模块与模块的命名冲突。如timer_prescalar_value, DMA_channel_name等;
  • 作用域前缀 (Scope Prefix) 标注变量的作用域,提高代码可读性:
    g_: 全局变量;
    n_: 局部变量;
    t_: 中间变量;
    s_: static静态变量;
  • 类型前缀 (Type Prefix) 指明变量的数据类型:
    ptr_: 指针变量,在程序中临时需要使用指针时,也常简写为p_,如*p_src;
    h_: 句柄,如h_file;
    n_: 整形,s_: 短整形,l_: 长整形, u_: 无符号整型,可增加数据位数,如u32;
    ch_: 字符型变量;
    f_: 浮点,d_: 双精度浮点;
    b_: boolean;
    by_: byte字节型(关注数据的位特性,需要位操作的情况下使用);
    reg_: 表示寄存器;
  • 后缀 (Suffix) 指明变量的性质:
    _src: 源,_dst: 目的;
    _str: 字符串;
    _t: 在声明数据类型时使用,表示为自定义的数据类型,如u32_t;
    _st: 表示为结构体;
    _buff: 数据缓冲, msg_buff;
    _arr, _a, _m: 数组或矩阵;


  • 循环控制变量 i, j, k, m, n,除循环控制外应避免使用这些变量名称;
  • 函数名 使用(模块名 + )动词 + 名词的形式,同样小写 + 下划线:sys_find_file(), IO_get_data(). 后者因为IO为专用名词故破例使用大写;
  • 类名或结构体名 使用首字母大写加下划线连接:如Mystring, Datetime_type;
  • 私有类成员 Private使用下划线_前缀,如_data_src_ptr, _init_module();
  • 宏定义或常量 使用全部大写:如MAX_NUMBER, LOOP_NUMBER;
  • 缩写 使用能广泛接受的缩写:如add, ans, avg, chk, cnt, col, ctrl, def, del, dst, disp, err, freq, idx, init, len, min, max, mid, msg, num, opt, pos, ptr, recv, res, ret, src, str, sub, num, ts (timestamp), val等。



KickStarter是国外最著名的众筹网站。项目发起者可以在只有基本idea的情况下提前发布产品信息,以获得来自个人的资金支持,达到满意的标准后再进行产品的实际生产,从而减少了产品发售的风险。 这几天在KS上比较热门的科技项目都是智能设备/可穿戴设备,这里我聊一聊几个我最近关注的项目。

1. Sweep激光雷达


▲ 图1. Sweep低成本激光雷达

激光雷达是机器人常用的传感器外设,用于快速扫描、感知环境存在中的障碍物。激光雷达通过激光旋转扫射,再测量激光返回时间的方式,对周围障碍物的距离进行快速估算。传感器输出的点云数据可以进行三维建模,最终辅助机器人进行导航。目前常用的激光传感器品牌为 HOKUYO,售价在几万至几十万元。传统的激光雷达使用光学振镜进行激光扫描,通过计算激光束相位差进行距离计算。而低成本的激光雷达通过电机控制激光的发射角度,使用视觉原理进行距离估算。在牺牲了扫描速度的情况下,大幅度降低了成本。关于低成本激光雷达的设计原理,可以参照CSK兄的博文:自制低成本3D激光扫描测距仪(3D激光雷达)

▲ 图2. Sweep工作在四轴飞行器上(慢速摄影)

以下是由IEEE Spectrum网站整理的Sweep与其他常见激光雷达的参数对比。Sweep的价格只有专业激光雷达的1/5,但刷新速度(Scan Rate)只有专业传感器的1/4。其检测距离精度为1cm,精度为1 – 2%,可以满足一般的机器人地图构建与导航应用。图表中的 robopeak 现改名为 SLAMTECRPLIDAR 也在最近推出了新款 RPLIAR A2,在性能上相比一代做了很大提升 (10Hz刷新率),价格和Sweep也很相似。目前Sweep的众筹已经结束,最终筹款$272,990,共有1,010个支持者。官网上可以预购,价格为$255,折合人民币1680元。

▲ 图3. Sweep与其他激光雷达的参数对比


2. Pebble 2智能手表


▲ 图4. Pebble智能手表第二代

大名鼎鼎的智能手表先祖Pebble再次回到KickStarter。这次他们带来的是最新的两款手表产品:Pebble 2和Pebble Time 2。前者是廉价型,后者为Premium高级版本。这次新版本的Pebble相比上一代的主要改变有:

2、增加了麦克风外设,支持语音信息回复,应该还可以通过Google Voice (Android) 和Siri (iOS) 进行语音控制);
3、核心处理器从Cortex M3升级为M4,有更大的信号处理能力;
5、Pebble Time 2实际上是上一代的Pebble Time Steel,Pebble Steel这个型号可能不会再推出。

▲ 图5. Pebble 2和Pebble Time 2

▲ 图6. Pebble 2有五种可选颜色

新产品的两个版本Pebble 2和Pebble Time 2两者的主要区别有:

1、Pebble Time 2的屏幕尺寸更大 ,同时使用的是彩色e-ink屏,而Pebble 2是黑白灰度e-ink屏 (e-ink即Kindle所使用的电纸屏,功耗极低);
2、外观和材质上,Pebble Time 2更佳,Pebble 2则看上去比较廉价;
3、当然,Pebble Time 2的价格比Pebble 2多70%。

Read more »







2016年04月21日 于 英国约克



  • 更高的处理速度。树莓派3首次采用了64位处理器:基于Cortex-A53的博通BCM2837。BCM2837为四处理器核心,主频也由树莓派2的900MHz提高到了1.2GHz。根据官方提供的数据,这将使树莓派3的处理速度较2代提高50%。如果和1代的700MHz单核相比,提升大约在3 – 4倍。更高的CPU速度使得树莓派可以胜任更大负荷的运算工作:如科学计算,机器人路径规划等。
  • 更高的互联性。树莓派3使用了集成蓝牙4.0和WiFi的设计。集成通信的设计的意义是多方面的。首先,使用者无需再购买额外的USB设备,从一定程度上来说,鼓励了用户在自己的设计中使用这些通信功能;其次,集成的通信模块可以进行更好的功耗管理,同时IO吞吐的性能也会得到提高;最后,可以更进一步的优化内核,只针对板载的芯片专门进行优化。避免可能出现的兼容性或者未优化的驱动导致通信性能下降问题。

图1. 树莓派3外观

图2. 树莓派3外观 (设计渲染图) 



表1. 发布时间及主要特点

型号 发布时间 主要特点
PI 1 Model B 2012年02月 第一代树莓派。Model A不含以太网。
PI Compute Module 2014年04月 模块化设计,使用SODIMM大小的金手指接口。
PI 1 Model B+ 2014年07月 增加了2个USB接口,增加了9个GPIO:26脚->40脚。
PI 2 Model B 2015年02月 升级处理器:四核900MHz Cortex-A9。升级为1GB RAM。
PI Zero 2015年11月 无网络通信功能,廉价,小尺寸。
PI 3 2016年02月 升级处理器:64bit四核1.2GHz Cortex-A53。


表2. 树莓派历代版本硬件比较

型号 处理器 主频 内存 GPIO 互联性 功耗级别
PI 1 Model B BCM2835
700MHz 512MB 26 2 USB
10/100M Ethernet
700mA (3.5W)
PI Compute Module BCM2835
700MHz 512MB 0 无。需要配合扩展板使用。 200mA (1W)
PI 1 Model B+ BCM2835
700MHz 512MB 40 4 USB
10/100M Ethernet
600mA (3W)
PI 2 Model B BCM2836
(Cortex-A9 四核)
900 MHz 1GB 40 4 USB
10/100M Ethernet
800mA (4W)
PI Zero BCM2835
1 GHz 512MB 40 (无排针) 1 Micro-USB
160mA (0.8W)
PI 3 BCM2837
(Cortex-A53 64位四核)
1.2 GHz 1GB 40 4 USB
Bluetooth 4.1
WiFi 802.11n
10/100M Ethernet
800mA (4W)


Read more »

机器学习 | 机器学习入门知识


机器学习 (Machine Learning) 研究的主题是如何让计算机具备与人类同等的思考和分析能力。机器学习主要基于认知学、计算机科学,统计概率学以及信息决策学。典型的机器学习应用包括照片分类、垃圾邮件识别、自然语言处理等。最近很火热的围棋人工智能AlphaGo就是采用了深度神经网络对大量棋局进行学习,从而具备了顶尖围棋选手的水平。

– 经济学模型建立
– 图像处理和机器视觉
– 生物DNA解码
– 能源负载、使用、价格预测
– 汽车、航空和制造
– 自然语言处理
– … …

Machine Learning从其采用的学习方式来说有以下三大类:
– 监督学习 (Supervised Learning):用于训练的数据包含已知结果(回归与分类问题)。
– 无监督学习 (Unsupervised Learning):用于训练的数据不包含已知结果(聚类问题)。
– 强化学习 (Reinforcement Learning):用于训练的数据不包含已知结果,但是可以用Award函数对其进行评价。

▲ 图. 机器学习的分类(图中没有强化学习,一般强化学习会被认为是semi-supervised)[1]





▲ 图. 常见Machine Learning算法的思维导图,点击放大 (Picture from

除了主流的聚类,回归和贝叶斯之外,采用神经网络的Deep Learning深度学习是现在最热门的话题。机器学习的方法很多,在选择使用什么方法时,首先必须要确定自己所面对的是哪一种机器学习问题。在确定了分类后,可以根据下图选择具体方法:

▲ 图. Machine Learning算法的选择 [1]


[1] Introducing Machine Learning, Mathworks





int fun1(int x) {	// fun1是函数名
	return x + 1;	// 函数体


物理地址 数值  说明
0x20000000        30 <– x是该数值单元的别名

x是内存单元0x20000000所对应的内存单元。此处x = 30,而x的地址&x = 0x20000000.


物理地址 数值 说明
fun1 (0x08000200) fun1_entry <– fun1是函数的入口地址

在这里,函数名代表一个记录了函数入口地址的存储单元的物理地址。可见,函数名的本质是地址。在编译阶段,函数名被转化成为对应的地址。在使用 xxxx() 函数调用的语法时,该地址被载入程序计数器PC,函数参数及当前现场被弹入堆栈。最后进行函数的实际跳转和执行。



物理地址 数值  说明
0x20000000         30 <– x是整形变量
0x20000004  0x20000000 <– p是指向x的指针

这里p是指向x的指针,(即p = &x)。此时p的内存单元所存储的是x单元的物理地址,通过 *p 解析地址之后就可以访问或修改x单元的内容。同样的,函数也有其对应的指针 – 函数指针。函数指针是一种特殊的指针,其指向的对象不是变量而是函数。函数指针指向目标函数的入口地址(首地址)。这里我们定义一个指向fun1函数的函数指针pf:

int fun1(int);		// fun1是一个(含int输入参数和int返回参数的)函数
int (*pf)(int);		// pf是(指向返回int型,含int参数函数的)函数指针
pf = &fun1;

/* 也可以直接写成: */
int (*pf)(int) = &fun1;

/* 如果需要调用函数指针对应的函数,可以写为:*/
(*pf)();		// 等价于fun1()


(*fun1)()		// 等价于fun1()
pf = fun1		// 等价于pf = &fun1;
/* 但是fun1的值不能被修改 */
fun1 = fun2		// 错误!fun1是const类型的指针


typedef int (*PF)(int); // 声明PF是一个函数指针类型
PF pf1 = fun1;
PF pf2 = fun2;



typedef int (*CALLBACK)(int);

#define EVENT_1		(0x01)
#define EVENT_2		(0x02)

int set_event_callback(const int e, CALLBACK);

void init_callbacks() {
	CALLBACK pf1, pf2;
	set_event_callback(EVENT_1, pf1);
	set_event_callback(EVENT_2, pf2);


void change_function(int nEvent, PF *ppf) {

	switch (nEvent) {
		case 0: 
			*ppf = fun1;
		case 1: 
			*ppf = fun2;
			*ppf = fun3;

这里利用了函数指针指向的函数是可以改变的(而非函数名是const型的)。change_function() 将函数指针的地址(指向函数指针的指针)作为参数传入,并根据当前nEvent的情况更改原函数指针指向的函数。


// 或


typedef void (*PF)(void);

// (*(void(*)(void))0)() 等价于
// 或



[1] Kenneth A.Reek, C和指针(第二版), 2008, 人民邮电出版社

[2] Brian W. Kernighan / Dennis M. Ritchie, The C Programming Language (Second Edition), 1989, Prentice Hall

[3] C语言中文网,C语言函数名与函数指针详解