某些高人在炫耀实验成果时,常常忘记附上实验数据,只有图表。所以我们这些低贱的盗版人士只能截取其画面,而不能做进一步的数据挖掘。我个人还曾经为了获得清晰大图,动用Illustrator重新描边,好不麻烦!
我于是决定写个“自动抄表”的工具。根据个别已知的精确值,推算其他未知的数据。以图中这张TIOBE的Java趋势分析为例。假设我们知道最近2年来每个月份的数据,怎样得到更早的数据呢?
首先我们要从原图中得到清晰的曲线。建议在绘图软件的帮助下,将曲线部分标出,以曲线部分的色相、饱和度、明度与其它部分有明显的差异为准。得到曲线后,得到每个x坐标中的y取值的平均值(中点)作为该时刻的曲线取值。
然后我们选取2个有精确数据、并且在图上有明显拐点的样本作为校准的依据。比如已知2010年1月的值是17.482、2006年1月的值是22.28226。那么可知变换公式是x' = 0.1846847 x -5.504501、y' = -0.03158065 y + 28.04573。因此可以计算得到其他各点的估计值。
为了保存运 ... (全文...)
为了评估无线传感器节点使用电池供电能够坚持多久,[tc]写了这个计算器。
在界面中输入电池的容量、全系统单周期内每个电流持续的时间(如果电压有变,请自行换算到电池电压),计算器会告诉你该系统理论上可以续航多长时间。如果总时间超过1年,这才是个基本可用的系统。
程序本身没什么技术难点。唯一的问题是由于在WSN中可能会长时间休眠,图像如果使用线性坐标会影响观感,所以采用的是对数坐标轴。
源代码+二进制:batterylifecalculator
一度以为Fedora Core做什么ubuntu就做什么。例如ubuntu 9.10以及ubuntu 10.04提高启动速度的原理,与Fedora Core同出一辙。不过我们也能渐渐感觉到,整个Linux低层都在悄然转向相同的目标。例如这一次撤销HAL的事件,也在Xorg中得到了验证。整个2010年1月份的Xorg更新几乎都与否决HAL有关。
[为什么抛弃HAL]
HAL全称为硬件抽象层(Hardware Abstraction Layer),顾名思义是为了屏蔽硬件种类的不同而提供的统一接口。
然而随着历史的变迁,在实际使用过程中,HAL已经退化成向应用层提供当前系统的设备列表的功能,包括物理设备、逻辑设备、网络API等信息。同时,当设备信息发生变化时,提供向上通知的机制。例如USB设备的插入、D-BUS查询变更、以太网链接事件、挂载点变更等功能,往往与HAL有关。
另一方面,在旧有的体制下,一旦调用完HAL_InitDevices(),设备列表事实上只能增加不能减少,也限制了HAL的应用。正是由于HAL已经不再表达其设计初衷,而设计灵活性又不高,所以抛弃HAL也是早晚的事。
更何况如今HAL被检测出对计算机启动时间有较大的影响,难怪Xorg、Fedora Core、ubuntu先后将计划付诸实施。
[没了HAL,用什么]
硬说HAL是忽然被移除的,这也不是事实。Linux内核为抛弃HAL ... (全文...)
年轻的[tc]曾以为学校是个搞科研的地方,现在才知道科研只是冰山一角。越来越多的学校加入到产学研的行列中来,让学校成为打造工业半成品的地方。
[工程项目不是万能的,但是很实在]
论文数量是每一个学校争宠的目标。这是因为工程往往局限于具体的事务,缺乏理论性和前瞻性,因此无法收录在国际知名文献索引中;如果以盈利为量化标准,又必然成为某些自认清高的知识分子炮轰的对象。
另一方面,执导工程项目又需要资深的工程人员,这也不是每一所学校的每一个部门都能够实现的。这在大部分情况下,导致搞科研的目的,仅仅是为了混毕业、评职称,给学校带来大批意义不大的文字材料。
实验室靠什么生存。靠国家补贴?靠大牛捐献?靠人的意志力?都是完全不够的(但是苏州这边出了一个教育投资公司,设备设施归园区所有,实验室有使用权,很大程度上缓解了学校的压力,算是个制度创新)。因此,现实上也只有将工程引入学校,抛弃让学校变得拜金的困扰。
[一块地方四种人物]
要想做工程,学校需要由四种人构成:一是拉皮条的,二是包工头的,三是赚外快的,四是吃干饭的。四者的比例应当是1:3:9:27,才能保证学校总体还是个教书的 ... (全文...)
挖坑篇:以下只是我的猜想,先不要上升到理论高度好了。
[从信号发生到谐波分析]
高中时代的[tc]由于接触Midi的关系,误以为信号分析是从时域下手,获得ADSR(Attack-Decay-Sustain-Release)参数;而知道正弦波是单音(Single tone)信号这已经是大一的事情了,当时最爱做的事情就是把多个单音信号叠加成一个混频信号;大三忽然知道FFT是做频域分析的捷径,所以偏执于把MIC的信号拿来做实时分析,然后郁闷地发现ARM9的性能也不是非常好。
会回顾这一系列历史的原因在于,用量化的信息评估语音信道的质量并不是非常容易。尤其是当两个系统的性能接近时,用人耳已经难以分辨好坏。但是我们也知道,单元测试不能遍历所有可能的情况。所以冥冥之中,我们还是需要一个有说服力的数据证明,方法A优于方法B。
[总谐波失真,对你很失望]
(全文...)
今天忽然发现VSPM的UDP传输模式故意没有实现流量控制,这与真实的串口行为不符,所以就用软件方法实现了流控。
[用VSPM实现虚拟串口回环]
VSPM区别于某些又垃圾又昂贵的商业软件的是,它是免费软件,而且思路很好。通过把串口数据透明转发到网络上,实现了远程虚拟串口的功能。当然,我们只要把网络地址改为本级地址,就可以实现串口回环。
例如:原本你写的串口通信程序占用了COM1,通信过程如下。
设备 <--> COM1 <--> 应用程序
而为了编写模拟器,我们需要模拟出COM1的行为。
设备模拟器 <--> COM5 <--> COM1 <--> 应用程序
其中COM5与COM1之间的通讯可以是真机通讯,也可以是虚拟串口通讯,我们把虚拟串口通讯称为“回环(Loop Back)”。意为把原本应该发送到串口的数据原样送回本机。
为了实现上面第2种结构,我们只需:
- 修改VSPM为UDP模式
- 在设备管理器中,把真机COM1改为COM10
- 新建虚拟串口COM1,监听127.0.0.1,接收端口7101,发送端口7102
- 新建虚拟串口COM5,监听127.0.0.1,接收端口7102,发送端口7101
是不是很像交叉电缆的接法?
[用Timer实现UDP的流量控制](全文...)
最近半个月,先是yo2的文件服务器没办法访问,这一周居然连www页面都没办法访问。不过今天忽然发现了这篇IP更换的公告:
公 告
接带宽提供商通知,原我们使用的 60.28.222.98 这个 IP 地址,现更改为 60.29.250.75。如果有用户直接将域名指向 60.28.222.98 的,请自行更新为 60.29.250.75。谢谢!~
这就难怪Firefox不能访问了,在etc/hosts里面强行加上
60.29.250.75 tctianchi.yo2.cn
60.29.250.75 yo2.cn
60.29.250.75 yo2cdn.com
60.29.250.75 extra-001.yo2cdn.com
就可以了,不过upload-001.yo2cdn.com还是没办法访问,让我们再等等好了。
在此前的文章中,我曾用Timer解决MVC模式中,Event合并后GUI不是最新状态的问题。此后glascholar同学认为这个Timer是不必要的,我于是按照这个指示修改了程序。今天忽然发现,第2个程序是不严谨的,所以现在重新实现之。
[上一次错在哪里]
在《合并-改》一文中,采用了2个Flag。其中一个表示未被处理的Event数量(HasUnprocessedEvent),另一个表示GUI更新是否结束(IsUpdating)。但是判断GUI结束(!HasUnprocessedEvent)到真的结束(IsUpdating = false)之间是非原子的。
假设Event的发起线程代码如下(忽略原子性):
而GUI线程响应RaiseUpdateEvent的内容如下(忽略原子性):
考虑下面 ... (全文...)
有些人的想法果然是个谜。当我想要查阅C#中Color常量列表时,发现大部分人提供的颜色列表是按照字母顺序排列,而不是按照Color下拉列表中的顺序排列的。
文后的程序,就是按照色相顺序排列的颜色常量列表、并且保存为html表格的程序。首先是颜色列表:
(全文...)
|
Color [Black] |
#000000 |
|
Color [DimGray] |
#696969 |
|
Color [Gray] |
#808080 |
|
Color [DarkGray] |
#A9A9A9 |
|
Color [Silver] |
#C0C0C0 |
|
Color [LightGray] |
#D3D3D3 |
|
Color [Gainsboro] |
#DCDCDC |
|
Color [WhiteSmoke] |
#F5F5F5 |
|
Color [White] |
#FFFFFF |
|
Color [Transparent] |
#FFFFFF |
[注意]
本文所述观点已于2009.12.11被认为“不够严谨”,改进方案请移驾到
这里。
在上一篇文章中我说到,因为Event合并导致GUI最终显示的不是Model的最新数据。为此我加入了Timer来刷新。而glascholar同学对此表示出不屑的态度,并给与了提示。
[glascholar的思路]
问题的关键是在于,耗费巨额成本的GUI在运行完成之后,许多Update Event都被忽略了。所以只要在GUI运行结束后,判断是否有Event被合并即可。
方法就是在运行GUI的delegate之前,先将一个标志Reset掉;每当有新的Event来时,设置这个标志;当GUI运行结束后,再次判断标志是否存在,如果标志非空,马上重新刷新GUI。这样就节省了最终的Timer。也就是说:
* Event到来 -> 设置Flag
* Flag还在 -> Flag Reset -> 处理GUI -> 循环
另外需要注意的是,Event是否到来的标志需要在Model线程与GUI线程共享,因此需要保持原子性。我们假设这是用锁来实现。
[该思路存在的问题](全文...)