少爷的凉粉

本少爷曾经卖过两年凉粉,对这小吃食也算颇有心得。可惜上大学之后再没机会做了,为了不让妙法湮灭,在此详述。

须知中华的凉粉,有南方凉粉与北方凉粉之分。这里说的是北方凉粉。

凉粉这东西,再简单不过。水与淀粉,足矣。

须知淀粉应是考究的,下品淀粉色泽、味道、口感皆不及上品。淀粉或由绿豆制成,也有用番薯、土豆。常法制凉粉皆选绿豆淀粉,颇有风味。然绿豆淀粉颜色阴沉,不及土豆淀粉通透洁白。土豆淀粉又比绿豆淀粉做的凉粉弹性好,口感佳。故此少爷的凉粉皆是土豆淀粉所制。

然土豆淀粉价本就高,凉粉也就贵了。然而物皆有值,小孩子说不得谎,旁人也都信得。一元一块,从不讲价,生意却也凑合。

有了淀粉,还需准备容器。居家做凉粉,可准备一两小盆,不要太大。还要一只锅子烧水,一只温度计察水温。

既是淀粉与水,必有个比率。水多了有水泡,会散;水少了会结块,也会散。口感不佳的凉粉是最要不得的。按体积算,淀粉与水一比五最佳。可在盆上做个记号,知道水到哪里合适。或者按照盆的大小,量取淀粉。

常人必会教你将凉粉与凉水放入锅里煮,这般则大错。淀粉与凉水混合,结块是免不了的。煮要的时间长,凉粉的色泽口感都会有损。等熬成了浆糊再凝固,必是不好的。我所说的办法,是热水冲泡,用极短的时间混合,等待逐渐降温。

首先是烧水了。做凉粉的水需是软水,硬水会令凉粉结块。水要先烧开,然后关火等温度降下来。到摄氏八十五度时,将热水冲入盆中与凉粉混合。然后迅速搅拌至均一,用洁净的布覆在盆口。需要透气,散去热和水汽,因此不能用盖子。静後半日,便可打开了。

凉粉是一整块的,吃的时候需要用刀切或者漏过钢丝网筛,切成细条。凉粉本无味,独本少爷独爱白水的凉粉。常人或辅以醋、酱油、盐、辣椒等佐料,这全凭自己口味了。少爷体质敏感,平生碰不得辣,故而辣味的是从来不食。

凉粉这物看似能存放数日,其实不然。凉粉第一日做得,第二日吃尚好,第三日则不可再吃了。要知凉粉如生物学用的培养基一样,是易生菌的,夏日更是如此。犹记得当年天若忽有阴雨,当日的凉粉卖不掉。只好转而相送,敦亲睦邻。实在多的,也只好弃了。

做人就和这凉粉一样,不好的凉粉,宁可扔了。

GUI还是CLI

很久之前我看到一位博友写到GUI(图形用户界面)和CLI(命令行界面)的设计哲学,中心含义是:两者各有优劣,无法说哪种是最好。这里我用同样的标题,谈谈另一个方面的问题。

的确,两者都有优点和不足。

图形界面更加直观,更符合初学者的类比逻辑。点几次窗口上的叉号就会明白它会关闭窗口。鼠标和触摸是伟大的进步,让操作更加自如。而这方面就不是命令行能达到的。面对一个黑色的终端,你能想象下一步应该敲哪个命令吗?或许高手可以,但大部分用户甚至不知道如何切换目录。从这一方面说,图形界面往往比命令行易用。

但并不绝对。有时候你要进行一些稍稍高级的操作,比如将所有文件名中的“LibreOffice”替换成“libreoffice”。用一行命令就可以解决的事情,你可能需要手动操作数百次,花费几个小时,或者要去找一个合适的工具软件,甚至自己编写一个……

不过命令行的便捷是有风险的,如果使用过命令行,你一定会遇到。如果你在命令行里用“rm”删除了一个文件,很遗憾,你再也找不回它了。你可能在批量操作时输入错了一个字母,结果是你不得不一个一个去把它们改回来,有时是无法恢复的。

命令行的设计哲学是100%相信人。它假设每个用户都能记住命令的用法,并准确无误地通过键盘输入。但人对命令的记忆是非常困难的,而且是会犯大量错误的。一个计算机高级用户生病住院半年,就忘掉了如何用命令行设置无线网络。如果你每分钟输入上百单词,那么出错也就不足为奇了。对着黑白的屏幕,闪烁的光标,犯错的几率会更高。而它的另一个观点是,软件总会出错,所以越复杂、功能越多的软件越是会漏洞百出。所以命令行程序都尽可能简单,操作方式尽可能单一。你会发现所有的命令行选项参数都那么严格,那只是为了减少混乱。如果你想玩转它,请花时间记住正确的命令和选项吧……

图形界面的设计哲学是不相信人。它认为每个用户都会犯错,而且他们记不得那些命令甚至快捷键,没有时间查使用手册。所以软件会有形象化的图标,会运用大量通用的界面设计架构(菜单栏,工具栏,内容区域,状态栏,滚动条),一些仿照现实物理现象的操作(拖动,按钮,滑块)。这一切都是为了让用户很容易被提示,即使不阅读帮助文档也能操作。设计者会假设用户可能犯的各种各样的错误,做出不同的反应或提示。用户刚想关闭窗口,就被提示“是否保存?”这会阻止用户进行误操作。但弊端是软件会变得相当复杂,为了避免用户忘记保存,不得不引入自动保存系统。用户会很欣然接受,但却是软件设计者的噩梦。

Google Hosts

我不是坏孩子,我只是想在Google+上联系好朋友……
继续阅读 →

开源新手的生存技能

曾经是个什么也不会的菜鸟,一头闯入开源世界。虽然现在依然与开源大佬差距很大,但总算是在这个神奇的世界生存下来了。

在开源社区混迹,有一些必备技能还是要学习的。

计算机知识

开源技术往往和计算机有关系,即便做的是硬件,也需要和别人分享,这就用到计算机和网络。

给你的计算机装一个GNU/Linux吧,这除了让你看起来更酷,还会让你领略开源的精髓。从很大程度上来说,开源即源于Linux。它的很多理论和技术,如此广泛的应用于开源世界。

网络技术

知道如何上网,并掌握常人不会涉及的网络技术,是很有用的。你需要让自己的设备总是能连接互联网。拥有一个强大的浏览器和精选的神奇插件,可以替你自动刷论坛。学着用FTP吧,这种古老的方式,现在看起来依然简单有效。熟练地收发邮件,与外国朋友友好交流。玩转邮件列表,乐在其中。熟悉IRC帮助你快速和其他人沟通想法,虽然它简单得好简陋。

必要时,你会自己搭建FTP或者网站,那些服务器知识其实并不复杂。

CVS,SVN和GIT

这三个工具是联系全世界开源人士的重要桥梁。有了它们,所有人可以更简单地控制大量的代码版本。如果你要为某个开源软件贡献代码,编写文档,甚至翻译,都肯定会需要它们。

命令行

不论是在Windows还是Linux操作系统中,会使用命令行都是从普通用户晋升高级用户的标志。虽然很多功能已经图形化,但仍有一些重要的部分,需要用命令行实现——比如你要关掉X图形服务,并让其重新启动。使用命令行有时会比图形界面更有效率,比如你要将文件名中含有“linux”的文件批量修改为“GNU/Linux”,只需要用一行命令就可以做到。最后,对着黑白的终端敲命令行总是让男孩子看起来更酷。

在命令行里进行简单文件操作,编辑文本文件,运行命令行程序,编写Shell脚本,可以帮你体会一种古典的思维方式。你可以将所有命令设定好,等它们执行,然后去喝杯茶。

Wiki

这里说的主要是MediaWiki,也包含其衍生物。Wiki是一个重要的在线协作平台。大量开源项目使用它来管理重要的文档、帮助。使用强大的Wiki获取内容,并将自己所知发布,与世界各地的人无缝协作。MediaWiki的下一个版本将拥有可视化编辑器,但晓得Wiki语法还是很有帮助的。如果你已经了解HTML,那么Wiki语法就非常简单了。

Bugzilla

如果你遇到一个Bug,可能会非常沮丧。但不要只是这样,花一些时间汇报Bug能帮助开发者修正错误,让更多用户受益。第一次使用Bugzilla可能会有些头晕:那些乱七八糟的Bug状态和标签是什么意思?很遗憾并不是所有错误追踪系统都一样,有些差异很大。不过通常你只需要花几分钟就会了解它,并且下一次就可以非常熟练。不同的错误追踪系统,原理和框架却是类似。一次学习,就能解决以后可能遇到的麻烦。

工业设计系教学建议

现状

工业设计系目前有两个专业:工业设计与艺术设计。两个专业的主要课程重合,又有些不同。虽然是针对工业设计专业所提,这些建议大部分也适合于艺术设计。

2010级工业设计主要来自第一批科技与创意设计试验班。从第一年接受了部分美术和设计基础课程,但实际上并没有很牢固。这些学生大多数都没有过美术学习经历,只能依样画葫芦,完成作业。而美术基础却是需要时间来反复磨砺的。而由于美术基础课会占用大量时间,科学技术类的课程,如数学、物理,则被大大简化。这对后续的教学产生了深刻影响。
在选择专业的过程当中,又有不少学生从两个工学试验班甚至医学、农学转过来。这部分同学是没有美术基础的。他们往往是在大二、大三甚至大四修读本该大一完成的美术基础课。这就导致整个工业设计专业的培养方案是被颠倒执行的。虽然从结果来看,学生修读完了所有学科的课程,但效果却与制定培养方案的初衷向违背。

艺术设计的学生原就是艺术生,美术积淀比较多,而在一些技术方面非常薄弱。原本工业设计与艺术设计在一起上课交流的目的即是优势互补。但实际上互补并不充分,尤其是对工业设计专业的同学,艺术和科技的能力都不突出。而与其他专业的交流,尤其是与计算机学院其他专业的交流,亦非常有限。

近年来,工业设计专业学生的发展有了更多元化的趋势。做产品设计的人少了,而做信息服务、软件交互设计、网页设计等新方向的人多了。原有的培养方案实际上是一个选择性很小的套餐,而不是像计算机科学与技术那样的模块化培养方案——就像自选餐。可选择不多的原因是工业设计系的课程非常少,而进一步的原因是教师数量太少,再进一步的原因是年轻教师的待遇太差。

工业设计的教师队伍人数不多。很多课程我们需要依赖外聘的老师,来自中国美院或者城市学院。仅有的教师也因为科研项目或者自己的业务经常出差,课程教学工作无法做到与学生充分交流,甚至有课程停上甚至研究生代讲的问题。这也导致了课程计划没能有效开展,甚至一些课程根本没有教学计划。没有执行课程计划,导致效率低下,不能保证教学目标达成,最终的损失还是要学生来承担。

工业设计的教育需要额外的硬件设施,就像计算机专业需要机房和电脑一样。各校办工业设计系,必备的有画室、摄影室、模型工坊。而这些工业设计系目前都没有,我们仅有几间刚刚够用的教室,(每个年级一间)而且硬件设施非常匮乏,投影仪坏了一年多没有修。设施缺乏导致很多课程,如立体造型、色彩构成,都无法开展。学生有一些好的想法,比如一些立体的造型,或者想把设计做成模型测试效果,都是非常困难的。艺术设计的学生学费比普通学生高一倍,但却没有得到相称的教学资源。

学院的四个专业中,其它三个基本上都是计算机类衍生的,管理和评价方法相似。但工业设计系的情况几乎完全不同,我们很少有计算机课,我们大部分课程属于课堂交流、工作坊形式的。而学院在统计课程评价的时候,经常忽略这一点。比如课程调查问卷,很多项是不符合工业设计特点的。像教学所使用的语言、教材的技术权威性等等。由于只有工业设计系在紫金港校区,学院的很多工作会忽略工业设计系,比如年级大会的主题基本都是与计算机和软件工程专业相关的,少有提及工业设计。

当前教学工作中,大量政治化和商业化因素在入侵。比如市政府办的创意杭州与我们的一些课程直接捆绑。还有一些企业的设计竞赛或活动,直接植入到课程里面。还有老师会将自己与某些公司的业务搬到课堂里面来,作为课程的课题作业。这样做虽然增加了学生实践的机会,但也有弊端。课程是有其专门的目的和安排的。很多精品课程的内容、课题选择、课时安排、教学目标,都是经过仔细推敲和严格控制的。而这些商业和政治活动的引入,将整个秩序都打破了,导致课程碎片化,教学目标偏离。

然后教学工作的监督评价情况。浙江大学对本科生教学工作的规定是非常严格的,但这些并没有在工业设计系的教学工作中充分落实。研究生代讲课、课程取消、到课率低等等情况才会普遍发生。如果学院在查课方面做得更到位,老师自然会更认真地对待教学工作。反之,老师可能会更愿意去忙自己的事情,放任教学工作的荒废。

教学工作组织不力的一大后果是学生的自由化。很多工业设计专业和艺术设计专业的学生感觉课程可上可不上,内容也无法吸引他们,甚至令他们很失望。因此他们会选择开辟自己的道路,由自己决定要做什么事。我们有的同学经常离开学校好几个月,音讯全无,考试不能通过只能休学;还有人在宿舍整日做自己的绘画创作,课程很少参加;还有不少沉迷游戏,无法自拔……而上游对下游的情况非常不了解,缺少沟通是非常可怕的。

培养方案建议

模块化

针对信息媒体设计、设计管理、传统产品设计等设置可选模块。学生只要完成一个模块即可结业,而不必去修读那些自己不感兴趣的课程。

去同质化

一些课程虽然名称不同,但却趋于同质化,比如计算机辅助设计基础,计算机辅助工业设计都是在讲CAD类软件使用。对这些课程进行合并精简,能够提高效率。

调整顺序

课程的先后关系存在一些问题。比如设计思维与表达课程,需要对设计已有比较多的认识才好开展,同时也需要CAD建模能力完成作业。而计算机辅助工业设计和工业设计史却都在这门课之后。

内容调整

建议课程中的电路原理、数字电路课程过于专业化,而缺少对设计整合的可用性,建议已其他课程替代,或者针对工业设计特点推出一门定制化课程。

软件工程课虽然是专业选修,但不在紫金港校区开课,10级几乎没有同学修读。建议在紫金港对工业设计开班,或者从培养方案中取消。

跨专业合作课程

与某个专业同学合上的课程。比如与数字媒体系的同学同上数字媒体设计,不同专业的同学结成一组,通过工作坊的形式合作。跨专业的合作有助于工业设计系的同学进行更深层次的互补,弥补当前工业设计和艺术设计内部交流的不足。

教学工作建议

增加教师数量

教师数量少的弊病如下:
1. 课程数量少,缺乏选择,很多应该跟上时代的课程找不到老师来开
2. 由于课程难以安排,一些老师不得不担任自己不熟悉的课程,课程无法充分开展
3. 部分课程只能启用外聘教师,而外聘教师对浙大工业设计可能并不了解

而增加教师数量必须提高年轻教师的待遇,尊重本科生教学工作取得的成绩。

课程监督有效化

目前学院的课程情况调查仅限于教务网的评价与纸质的调查问卷,而缺少实地的课上情况调查。

当前的现状是,在线点评和问卷并不能获得真实的情况,工业设计的教学内容和形式存在特殊性。到课率、老师的考勤都没有得到落实。

建议由专人进行各个课程的调查反馈工作。一方面监督课程的开展情况,一方面与学生互动沟通课程情况。

落实课程计划

每个课程都应当具有一个可执行的课程计划,不然无法保证课程目标的有效达成。这一点应当纳入到课程评价体系当中去。

课程计划的落实情况也应当受到监督反馈。教学计划更改必须有合理原因,教学计划无法完成也应作出解释。

项目与课程分开

像创意杭州这样的项目虽然是锻炼的好机会,但也容易把课程搞得一团乱。应该尽量将两件事分开,在课程中做创意杭州的项目并不明智。一些企业的商业项目则更应当让学生在课余时间自愿参与,系里可以组织相应的工作坊,避免干扰到教学工作的正常展开。

一切应为课程服务,而非课程为项目服务。

教学资源建议

增加必要教室

包括:
1. 模型坊,配备操作台和切割打磨等工具
2. 摄影室,摄像器材和幕布、反光板、灯箱
3. 画室,绘画素材和模型,可与其他专业共用
4. 专业教室,每个班应当有一个教室,三个年级六个班,应该有六个专业教室,但现在只有三个,50个人挤在同一个教室

专业教室优化

包括:
1. 改善网络状况

这些情况曾向学校相关部门反映过,但都不了了之。

自行车测速器

今天做了一个为自行车测速的传感器。原理很明了:在自行车轮圈上均布贴上黑色贴条,而轮圈接近白色,转动时灰度传感器就会采集到黑白交替的频率,以此确定速度。

灰度传感器模块由光电对射管和放大器电路组成,能以某一基准分辨反射灰度是偏黑还是偏白。这个基准可以通过调节电位器来改变。灰度传感器采集的是反射灰度,而非颜色实际的灰度,反射面的角度和距离都会产生影响。即使是黑色,在足够近的情况下也能反射足够多红外线。因此在使用过程中要调节。

采集频率是简单的,但如何采集到可靠稳定的数据就有不少麻烦。于是我们采用了连续采样拟合的办法,尽量避免速度的异常波动。

在控制指示灯的过程中,我们的电路装在自行车上,不易于连接电脑调试。我们用蓝牙模块接在Arduino板上,通过手机接收,解决了这个麻烦。

Arduino与Processing的串口通信

在网络上普遍存在的Arduino与Processing互动的例子,都具有一个很简单的构造:Arduino上用Serial.print()发送,在Processing中用Serial.readString()读取,或者反过来。然而实际应用过程中大家就会发现这个简单的逻辑模型会发生莫名其妙的错误。最显著的是有时候会收到空值,即使用Serial.available()检测,也会有时收到间断的字符串或者多个字符串混在一起了。

下面是一个经典的Processing与Arduino通信实例:

//Processing Code
import processing.serial.*;

Serial myPort;

void setup(){
  myPort = new Serial(this,"/dev/ttyACM0", 115200); //Set Serial Port

}

void draw(){
  if(myPort.available()>0){
    String message = myPort.readString();
    println(message);
  }
}
//Arduino code
int data=12345; 
void setup()
{
  Serial.begin(115200);//rate
}
void loop()
{
  Serial.print(data); //send data
  delay(1000);
}

然后我们期待着每次获取“12345”并显示在屏幕上,但事与愿违,我们得到的情况是这样的:

12345
123
45
12345
12345

输出时的中断是怎样产生的呢?要探究这个问题的根源,需要重新审视串口通信的原理。

串口通讯就像一趟公共汽车,每个字节是一个在等车的人。他来到车站(发送数据),车还没有来,所以新来的人就一直等待(缓存)。当公共汽车来了的时候,将这些人一次接走(读取数据),当然车也是有容量的,只能载一定数量的人(缓存大小)。现在有一个旅行团(字符串/字符数组),一部分人走在前面刚刚赶上了车(被读取),而另一部分人没赶上,只能等待下一班车(下一次读取)。另一种情况是,两个旅行团都在车站等车,被同一班车接走了。这就是为什么我们读取的时候字符串会断成两节,或者并起来。

核心原因是:串口流通的数据都是bytes而没有字符串概念,所有发送数据都会按一个byte一个byte缓存,不论是否是连续字符串;而读取时会取走所有缓存bytes,不论它们是否是一个、半个还是多个字符串。

Arduino和Processing的数据收发速度是不一样的。如果用Arduino延时较长时间,Processing可能读取一个字符串或字符串的一部分。如果Arduino延时较短,Processing可能读取多个字符串,但不一定完整。在读取字符串的时候,无法确定上一个字符串是否被读取了,当前字符串是否缓存完毕,因为字符串都已经切成了bytes,连成一串。这个问题是串口通信本身造成的,一定会出现。

一种解决方法是,通过在接收端缓存数据来解决这个问题。为传输数据设置一个结束标记,如'\n'(换行符),就能在接收到的数据流中识别到一个字符串的结尾。当未遇到结束标记,就一直将串口数据保存在一个buffer变量中,继续接收。

Processing的SerialEvent事件类型就提供了这种方式,使用bufferUntil(ch)可以在遇到某个指定字符时才完成缓存。

程序实例:

//Processing Code
import processing.serial.*;

Serial myPort;

void setup(){
  myPort = new Serial(this,"/dev/ttyACM0", 115200);  //in fact, any rate is ok...
  myPort.bufferUntil('\n');  //buffer until meet '\n', then call the event listener
}

void draw(){
  
}

//listen to the event. when buffer filled, run this method
void serialEvent(Serial p) {
  String inString = p.readString();
  print(inString);
}

//then the buffer will reveive all the bytes
//Arduino Code
int data=12345; 
void setup()
{
  Serial.begin(115200);//rate
}
void loop()
{
  Serial.println(data); //send data, end up with '\n'
  delay(1000);
}

当然,这种方法也可以用在普通的串口通信中,不必使用SerialEvent。接收的数据不直接使用,而是作为缓存。若未遇到结束标记,就继续读取下一次。当遇到结束标记,即完成缓存。

程序实例:

//Processing Code
import processing.serial.*;

String message;
String temp;
Serial myPort;

void setup(){
  myPort = new Serial(this,"/dev/ttyACM0", 115200); //Set Serial Port
}

void draw(){
  if(myPort.available()>0){
    temp = myPort.readString(); //temp for read bytes
    for(int i = 0; i < temp.length(); i++){
      //if meet the end mark
      if(temp.charAt(i) == '\n'){
        println(message);
        message = "";  //clean string
      }
      else
        message += temp.charAt(i);  //store byte
    }
  }
}
//Arduino Code
int data=12345; 
void setup()
{
  Serial.begin(115200);//rate
}
void loop()
{
  Serial.println(data); //send data, end up with '\n'
  delay(1000);
}

遥控变色灯

课程作业总是没完没了。有时候不得不日复一日地做同样的事情,虽然明明知道不久就会全忘掉。

早晨起来就开始琢磨这次信息产品课要做点什么。淘宝上买的蓝牙模块还没有送到,电脑无线互动做不了。而且第一周是基本练习,包括数字输入输出,模拟输入输出,串口上载和下载,开关。原材料也很少,电阻,LED,一个全彩LED,遥控器,还有光敏二极管,电位器,开关,小键盘什么的。最后选择了全彩LED和红外遥控器。全彩LED我是第一次用,红外遥控看起来很酷。他们拼起来便是一个遥控变色灯。

原理设想比较简单,通过红外遥控输入控制信号,使R,G,B值增减,单片机控制三路PWM输出的占空比,从而达到变幻颜色的目的。电路也很快搭好了,只接了两个元件:全彩LED,红外接收器。全彩LED使用了9,10,11三个PWM端口,而红外接收器接在13端口。
遥控彩灯原理图示意
Arduino有现成的红外接收库。一开始就非常顺利地接收了红外遥控的信号,并记录下了每个键所对应的值,这是通过串口发送电脑回来的。很特别的是,当一直按下一个键时,后续会重复返回FFFFFFFF。然后根据按键控制红灯的亮度,并设计成若一直按下,则会重复动作,这样就不必按很多次按钮了。

当我们如法炮制,添加了绿灯,一切正常,添加了蓝灯,却无法工作。按下蓝灯控制键,程序便会中断。这是为什么呢?我们开始一直以为是遥控的原因,更换了遥控上的其他键来控制,情况是一样的。后来我们又检查程序,将可能的错误修正。但依旧是红绿灯正常,而蓝灯不能使用。三个灯应该是对等的,如果其他两个没有问题,说明程序是可行的。既然该换了按键也没有用,说明遥控这部分也没有问题。我们将蓝绿调换,发现蓝色可以正常工作,说明全彩LED正常。所以最终有问题的是电路板硬件或者连接。蓝灯接入的11端口可能存在问题,便将其该换到6号端口,如此就解决了问题。

AVR单片机的6路PWM是有差异的。Arduino将其同质化处理,虽然简化了认知过程,但导致很多问题无法解释。机器人协会曾经也讨论过是否要引进Arduino,但后来还是否定了这个计划。因为Arduino的思维方式虽然在早期能够快速入门,但却导致在进阶的过程中处处遭遇困难。以后再去认识硬件细节的设计,摒弃原有的理解,是非常困难的。

IMG_0054

IMG_0055

IMG_0056

#include "IRremote.h"

int RECV_PIN = 13;

int red = 0;
int blue = 0;
int green = 0;

int last = 0;
int now = 0;
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;
 
void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(6, OUTPUT);
}
 
void loop() {
  
  if (irrecv.decode(&results)) {
    now = results.value;
    Serial.println(now);
    
    if(now==-1)
      now = last;
    
    switch(now){
      case -23971:
	if(red==0)
	  red=255;
	else
	  red--;
	break;
      case 25245:
	if(red==255)
	  red=0;
	else
	  red++;
	break;
      case 8925:
	if(green==0)
	  green=255;
	else
	  green--;
	break;
      case 765:
	if(green==255)
	  green=0;
	else
	  green++;
	break;
      case -8161:
	if(blue==0)
	  blue=255;
	else
	  blue--;
	break;
      case -22441:
	if(blue==255)
	  blue=0;
	else
	  blue++;
	break;
      case -7651:
	red=0;
	green=0;
	blue=0;
	break;
      default:break;
    }
    irrecv.resume();
    last = now;
  }
  
  color(red, green, blue);            
}

void color(int r, int g, int b){
  analogWrite(9, r);
  analogWrite(10, g);
  analogWrite(6, b);
}

机器人:俱乐部与实验室的差异

在大学里,我接触到了两个和机器人有关的地方:学生组建的机器人俱乐部,学校组织的机器人实验室。

这是两个不同群体的代表,在很多方面代表了深刻的差异。

机器人俱乐部是一个被兴趣驱动的群体,他们是非常社会化的。俱乐部的目标或许可以用其他语言来表示,但本质即是:自我的乐趣。不论是机器人带来的乐趣,还是这个过程产生的乐趣。我们是在玩机器人,不必去在意是否有用。

而实验室是有现实目的的,不论是研究成果,还是应用价值。被关注对象之外的东西牵制,导致这个过程逐渐模式化。引入工程管理方法,提高产出效率。这是在造机器人,有用的机器人。

MediaWiki MathJax数学公式

原理

MediaWiki的插件一般由php脚本和javascript脚本组成,直接上传到服务器,并在配置文件内添加插件路径即可使用。

Math插件的安装比较繁琐,因为它还依赖于其他本地应用程序,如mineTex。Math是一个统一化的接口,用户使用同样的数学公式代码,却可以通过不同方式生成公式。这些方式包括:PNG图片,LaTex,Tex,HTML,MathML等。而Math并没有实现这些功能的模块,需要调用其它应用程序。

目前默认的后端是Texvc,它可以生成PNG图片。这种方式需要服务器安装mineTex本地应用程序。然而对于共享空间上的站点来说,可能无法安装软件。PNG图片的显示效果也不好,在屏幕分辨率高的情况下不够清晰平滑,不能随文本缩放。因此,MediaWiki未来将会采用另一种表现更好的方式——Mathjax。

MathJax是一个开源的JavaScript数学公式显示引擎,适用于几乎所有现代浏览器。它被广泛应用于Wiki,WordPress博客等站点。使用它非常简单,只要在网页上的head标签内加入

<script type="text/javascript"
   src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

即可。对于WordPress,MediaWiki等平台,若需要在整个站点启用此特性,则应在站点皮肤的HTML/PHP脚本中添加。

可以看出,这实际上是调用了MathJax在线引擎,JavaScript脚本存放于远程服务器上。若是在本地局域网内不能访问国际互联网,则可以下载MathJax并安装在本地,链接修改为本地站点。

步骤

对于MediaWiki,通过Math插件添加更加方便控制,且能应用于所有皮肤中。

第一步,下载Math插件

第二步,上传Math插件。将插件解压并将文件夹上传到extension目录中,命令文件夹为Math。

第三步,注册Math插件。打开LocalSettings.php,在插件注册部分添加:

require_once("$IP/extensions/Math/Math.php");

第四步,配置Math插件。打开/extensions/Math/Math.php,更改如下几条配置信息:
1.关闭Tex

$wgUseTeX = false;

2.开启MathJax

$wgUseMathJax = true;

3.设MathJax为默认

$wgDefaultUserOptions['math'] = MW_MATH_MATHJAX;

Math默认调用MathJax官方网站的引擎。若你在不连接国际互联网的情况下使用,或者希望使用自己的服务器提高效率,可以安装自己的MathJax引擎。

第一步,下载MathJax引擎

第二步,上传MathJax到服务器。

第三步,修改Math插件配置:

$wgMathJaxUrl = 'http://yoursite.org/mathjax/MathJax.js?config=TeX-AMS_HTML';

URL修改为你的MathJax引擎所在的位置。

对于学校内,企业内,组织内的网络系统,可以搭建一个开放MathJax引擎,供所有内部站点使用。