Jul 29, 2008

良构的XHTML

良构的XHTML
  XHTML是一个万维网协会W3C标准,该标准将HTML定义成良构的XML文档。许多浏览器处理HTML都不严格,格式错误的HTML也能很好的工作然而现在正朝着更加严格的语法方向发展,以便增加web的健壮性。对于开发工具而言,良构的代码可以带来很大益处。同时,手工编写代码时,这也是非常有价值的,可以减少代码混乱和含糊不清
  良构的HTML遵循一下规则:
  关闭所有标签:
  某些HTML标签如

,,,按惯例是可以不关闭的然而良构HTML中必须包含关闭标签。如。某些标签如
,


,,可以将左斜杠放置在标签内关闭自身,这样成为良构代码
  禁止标签嵌套:
  This is the yearfor the Red Sox.
  应该改为
  This is the yearfor the Red Sox.
  区分大小写:
  同HTML和ASP相似,ASP.NET一般不区分大小写,一个重要的例外是,C#必须区分大小写。好习惯是遵循XML协定,元素类型和属性区分大小写。除由多个词组成的名称(onServerClick)使用camel命名法,以小写开头之外其他元素类型和属性通常都小写。HTML标签要成为良构的,则需要相匹配的开始和结束标签。
  引号:
  良构HTML中所有属性值置于引号中
  唯一的根元素:
  页面顶层元素必须是,末尾用关闭
  保留字符:
  XML中有五个内建字符实体
  < <
  > >
  & &
  " “
  ' ‘
  如果要在脚本中使用这些字符,必须使用以上字符实体,或者在一个CDATA字中放置整个脚本块(CDATA是一个XML类型)
  HTML控件分两种类型:输入控件和容器控件。HTML输入控件不需要关闭标签(尽管需要良构,但是它们可以在末尾加上/作为关闭)同时,可以通过编程方式访问和控制Name,Value,Type属性
  容器控件必须在标记末尾加上/或者关闭标签,他们不必有Name,Value或type属性。相反,位于控件打开和关闭标签之间的内容可以使用InnerHtml或InnerText属性标称访问。这两个属性不同之处在于InnerText属性提供自动的HTML特殊字符的编码和解码;如果使用InnerHtml属性,那么这些字符在做种输出中将被解释成HTML代码的一部分,并不作显示。

Jul 23, 2008

Pragma Directives

Each implementation of C and C++ supports some features unique to its host machine or operating system.

Some programs, for instance, need to exercise precise control over the memory areas where data is placed or

to control the way certain functions receive parameters.
The #pragma directives offer a way for each compiler
to offer machine- and operating-system-specific features
while retaining overall compatibility with the C and C++
languages. Pragmas are machine- or operating-system-specific by definition,
and are usually different for every compiler.

Syntax

#pragma token-string

The token-string is a series of characters that gives a specific compiler instruction and arguments,
if any.

The number sign (#) must be the first non-white-space character on the line containing the pragma;

white-space characters can separate the number sign and the word pragma.
Following #pragma, write any text that the translator can parse as preprocessing tokens.
The argument to #pragma is subject to macro expansion.

If the compiler finds a pragma it does not recognize, it issues a warning, but compilation continues.

Pragmas can be used in conditional statements, to provide new preprocessor functionality,
or to provide implementation-defined information to the compiler.
The C and C++ compilers recognize the following pragmas:

alloc_text comment init_seg1 optimize
auto_inline component inline_depth pack
bss_seg data_seg inline_recursion pointers_to_members1
check_stack function intrinsic setlocale
code_seg hdrstop message vtordisp1
const_seg include_alias once warning


This is an article from MSDN, I ever wanted to use
#pragma pack(1) //which can combine structure members to one continuous memory block
on MIPS platform using GCC, but it doesn't work.


See the compiler's document, it should be illustrated there.

Under linux env using intel-based GCC, it works.

Jul 19, 2008

MFC下文本框的使用(出现字符重叠现象的解决方案)

上次做了一个模拟股票软件的K线图界面
在右下角留了个公告栏
由于是画线图的界面
背景颜色最好是黑色的,线框是红色的,线是黄色的
这样看起来眼睛不会太累
画图的那个算法就先不提了,再做公告栏时就碰到问题

我将公告栏的位置固定在右下角
然后把背景色设置成透明
既捕获WM_CTLCOLOR消息然后把CEdit类的我所要放公告的类给SetBkMode(Transparent);
然后把字体设置成红色,勾起Auto VScroll(不让它出现讨厌的滚条)

OK,调试的时候发现了一个问题
用一个Timer去发同一条公告时,没超出文本框的范围还好
纵向超出文本框范围时,最底下一行居然出现了字符重叠现象
真是活见鬼啊
检查了一下我的代码没有问题
而且如果不auto滚动的话就没有问题
还真是···

上网搜索了一阵子
有几个人也碰到这样的问题,下边也跟了很多帖
仔细看了他们的解答,有个人是这么说的,不能把SetBkMode()里的参数设置成Transparent
就是这个问题
开始我还有点不信呢,可是看了那么多答案,还是这个最简便
可这问题也太··
到我的程序下一试
还真的是耶····

可这到底是什么原因呢?
我最后把这个Transparent改成了RGB表示的背景色
行了。
还是很奇怪,希望以后能够明白
就先把解决方案写下,问题留着,以后也许会有答案
积累积累···

Jul 18, 2008

RobotX

今天把RobotX给拆咯

原先机械组组装的时候没有将Servomotor进行调零(他们还不知道舵机有零度的)

所以只好把17个舵机一个个拆下来重新调,哎

貌似很难啊

初始状态要求比较严格,看来要花一阵时间咯

Jul 17, 2008

LabVIEW环境下的人型机器人仿真控制分析报告

一:扫盲篇
1:什么是虚拟仪器:
所谓虚拟仪器,就是用户在通用计算机平台上根据需求来定义和设计仪器的测试功能,由I/O接口设备完成信号采集,测量和调整,并利用PC已有的软件功能实现信号数据的运算,分析和处理;并利用PC显示器得显示功能,模拟传统仪器的功能面板,以多种形式表达(输出)检测结果,从而完成各种测试功能的一种计算机仪器系统。
2:关于LabVIEW软件
LabVIEW是由美国国家仪器公司(National Instruments Corp,简称NI)推出的一款虚拟仪器软件(Virtual Instrument,简称VI)。它是一个具有革命性意义得图形化开发环境,专为不熟悉传统文本编程的测试工程师设计,采用图形化编程方法,又称G语言。它有和传统编程语言有着诸多相似之处,如数据类型,数据流控制结构,程序调试工具以及模块化的编程特点等。
图形化编程是由数据流驱动的,与一般文本编程语言的过程驱动机制有很大的差别;LabVIEW在编写与工程领域设计,测量,控制等相关的程序或系统时,其开发效率高于其他语言。但是由于几乎是完全的图形化,调用的都是被封装好的功能,以至于做一些底层开发时需要依赖传统的文本编辑语言。
LabVIEW提供的图形化编程环境分为两部分,即前面板与程序框图。前面板用于设计UI,程序框图用于设计内部结构。

二:分析篇
首先分析Humanoid RobotX自带的编程控制界面。
该界面就是一个仿真控制界面。左半部为输入控件,主要是调整机器人身上所带电机的转角及转动方向,通过后台的一系列分析把输入控件上的输入值转换为电机的控制参数从而控制转动。右半部为图形化编程界面,通过在BEGIN和END节点间插入POSE来编写机器人的动作。每个POSE为一个动作模块,可以调节所有的电机完成一个动作模块,但其中涉及重心控制等内容暂时未了解。

将目前所学到的关于LabVIEW的知识,看过的实例教程与Humanoid RobotX自带的编程控制界面作比较,结果如下:
首先,实现直观的调节控件控制电机转角是可行的。在LabVIEW中,前面板的输入控件获取用户的输入数据(可以是直观的转角数据,或者是旋钮的转动角度,微调控件的位移距离等),转换为相应值,通过LabVIEW中的I/O接口输入到电路板上;
其次,POSE(动作模块)功能也基本可行,大体思路是设置一个适当的数据结构(当所有数据均为同种类型时)或簇(有不同类型数据),将其与所有输入控件相关联。当选中一个数组或簇时,调节输入控件,这时所有输入的数据都将传入数组或簇中(这里有个小疑问,如果某个动作中不使用某个电机,则该电机对应输入控件输入为空,对于这个空输入的处理还需要研究一下)。
将所有输入控件值获取到数组或簇中后,创建一个输入输出控件,输入为获取的数组或簇,输出可以通过LabVIEW提供的VC++接口或者MathScript接口来控制将对应的值输出到对应的电机。
最后是对机器人动作情况的实时仿真,这点很困难。首先需要有相应的传感器将机器人目前的各种状态参数传入LabVIEW中;其次,在LabVIEW中可以调用ActiveX控件,将参数输入控件中实现机器人状态的图形化显示。
问题就在于目前没有可以供这种实时仿真功能直接使用的ActiveX控件,如果要自行开发,需要的时间较长,而且需要专门成立一个开发团队。按目前的时间安排来看是完全不可行的。

三:总结篇
使用LabVIEW进行人形机器人仿真控制总体而言是可行的。但建议将它放到后边自主开发时进行。前期由于时间较紧,可以先用现成的控制软件在现成的电路板上进行操控。熟悉了现有控制软件结构后,可以为将来的自行开发控制软件打下良好基础。

四:附录
LabVIEW的接口:
【与C和VC++的接口】:LabVIEW与两者的交互是要C和VC++联合使用的。
C的作用是将输入的数据进行分类,处理和分配。而LabVIEW不能直接调用外部编写的C代码,需要调用.lsb格式的文件。
VC++的作用是生成动态链接库并将C文件转化为LSB文件。
由于VC++兼容C语言,所以可以完全的在VC++环境中进行相应的编程,完成LabVIEW做不到的某些功能。
【与MATLAB的接口】:相比之下,与MATLAB的接口就方便得多。LabVIEW中有MathScript控件,可以在上边直接写MATLAB的代码就可以执行。但是要求该计算机上必须已经安装了MATLAB。

Jul 12, 2008

直线的困惑

记得以前看过一个电视节目 
说的是一个人在晚上回家时走过一个必须路过的小巷 
结果那天晚上,平时只要五六分钟走完的路他走了两三个小时还是没有走出去 
以为碰上“鬼打墙” 

后来一群专家跳出来说世界上本没有鬼 
心虚的人多了,也就有了 
还如此如此这般这般的解释了一大堆为什么会走不出 
别的没记住 
后边的那个实验我记住了 
一个人蒙着眼和睁着眼走一条直线 
结果蒙着眼的人一定会走出一个大的圆来 
而睁着眼睛走路,走一条直线没有什么难度 

如今在调RobotX时也出现了这个问题 
机器人走路就是走不了直线 
这个问题着实困扰了我们很久,也花费了我们不少时间和精力
各种方案的提出与更改和决策
最后我们有了一个折衷的方案
这其中的问题很多,但是大部分可以从人身上找到答案 
必须要弄清楚的是,一个人是不对称的,不仅是脸 
他的全身无论什么都是不对称的 
人在走路的时候,由于这样天生的不对称 
两条腿的步幅是不一样的 
在缺少参照物的情况下,很自然的会走出一个圆圈来 
而人之所以能走直线(沿着一条直线走) 
是因为不断的用眼睛去观察参照物,随时修正自己的方向 
正是这种实时反馈和调整使得人们可以“向前走” 

而对于这个仿人机器人,他是由17个舵机驱动的 
舵机型号虽然相同 
可是本身的某些特性肯定是不可能做到完全一样的 
因为偏差和误差总是存在的 
比如说承重时偏移的一小个角度各不相同 
地面的粗糙程度不同 
还有本身调零的时候身体的平衡和对称等机械上的误差等 
都会在走路的时候对方向造成偏差 
这是不可避免的 
而对机器人的前进方向进行实时的调整又是一项费时费力的工作 
而且不经济 
所以我们采取的就是前进一定距离 
当偏差到达一定水平的时候停下来进行调整 

其实在调这个机器人的时候我就有挺多感触 
走路这件平凡无奇的小事 
我们做起来还真是不好做 
谁还记得自己当初是如何学会走路的 
谁会追究自己是怎么走路的,重心是怎么变的,起步时应该怎么做 
一定要自己亲手做过,亲自研究过,思考过 
事情的缘由和过程才会渐渐明朗起来 

所以我想在以后无论我做什么 
都要记住尽量避免蒙着眼睛凭直觉去做事 
即使的调整自己的状态 
以免陷入这直线的困惑里面 
这只是一点体会 
写出来大家共勉

Jul 11, 2008

引用和指针的区别

c++ Primer 与 effective C++都有提到这个区别,不过貌似深奥了点(虽然很详细)
以下为多方考证结果:

主要区别:
  一是 初始化问题:引用必须初始化
  二是 赋值操作问题:对引用赋值修改的是与该引用关联的对象
  引用一经初始化就不能修改(引用是const的指针,不许改变指向)。
  三是 不能定义引用类型的引用 但是可以定义指针类型的指针!

其实,很简单的一句话可以搞定:引用是对象的别名,操作他等价于操作原本的对象;而指针是一种变量,其值为对象的地址.

  经典的区分二者的程序:
  #include
  int main()
  {
  int ival=1024,ival2=2048;
  int *pi=&ival;
   int *pi2=&ival2;
   pi=pi2;
   cout<<*pi<<" "<<*pi2<<“ival= ”<  int &ri=ival,&ri2=ival2;
   ri=ri2 cout<   return 0;
  }

Jul 9, 2008

【典藏】网格计算

网格计算:下一代互联网技术
王亚章
  编者按:随着“下一代网络”蓝图的浮现,“网格计算”已成为人们关注的热点。但是,究竟什么是“网格”?它和电力网有什么区别与联系?推动和制约其发展的因素有哪些?请看北京大学计算机系研究员、电子商务协会CTO王亚章的精彩论述。

  一面镜子反射的阳光能量有限,但是众多镜子“集群”在一起,反射的能量就很大了。关于阿基米德的传说中,他指挥叙拉古城居民用众多镜子反射阳光烧毁了入侵的罗马帝国战舰,这就是一个极好的例子。现今,很多领域需要强大的计算能力,但是却没有能力配备足够高端的服务器。于是,人们将思路放到了“集腋成裘”上,这引发了“网格计算” 这一概念的出现。

  网格计算(Grid Computing)的由来是因为这种计算方式像格子一样的体系结构。它试图将过剩的计算能力以及其它闲置的IT资源联系起来,以供应给那些在一定时间内需要高性能计算能力的部门。2002年11月,日本国家高级工业科技研究所从日本向美国发送数据,速度高达707Mbps——在1万公里以上的距离之间以如此高的速度传送数据,这在世界上尚属首次,此次试验就是通过网格系统实现的。

  简单地讲,网格是把互联网上的众多计算资源整合成一台虚拟的超级计算机,将以CPU为主的各种资源“拧成一股绳”,实现各种资源的全面共享。当然,网格并不一定非要跨越国界,也可以构造地区性的网格,如城市网格、企业内部网格、局域网网格,甚至家庭网格等等——网格的根本特征,不是它的规模,而是资源共享。

  随着网格计算的发展,也有人把它看成是未来的互联网技术。国外媒体常用“下一代互联网”、“互联网2”、“下一代Web“等词语来称呼与网格相关的技术。企业界用的名字就更多了,包括内容分发、服务分发、电子服务、实时企业计算、分布式计算、P2P计算、Web服务等。这些名词所代表的技术有一个共同点,即将互联上的资源整合成一台超级服务器,有效地提供内容服务、计算服务、存储服务等。

  网格vs电力网

  为了更好地理解网格计算,我们先看看另外一种“格子”—电力网—是如何工作的。可以说,电力网的模式是网格努力的方向。在打开电灯的时候,几乎没人考虑他所用的电能是从哪个发电厂来的。

  互联网的情形如何呢?人们获取信息的时候,并不是直接从互联网本身获取,而是必须告诉计算机去访问某一个特定的网站—这就好比,我们在打开电灯之前,先告诉它我们需要从哪一个电站获得电能一样笨拙。网格的目标,就是让人们使用网络资源像用电一样简单。而且,值得注意的是,一旦某家工厂用电量激增,可以凭借电网上为数众多的电厂有效分解这一负担—如果这家工厂不采用电网供电,而是单独使用自己的发电机工作,恐怕将自己的发电机“累疯”了也“难以为继”。电力网上有效解决负载平衡的经验,也是网格的发展方向之一。

  理解了电力网模式,就易于理解网格计算能够提高企业计算机利用率的问题了。许多企业每年在信息技术方面的投入都相当巨大,但是仍然不能满足工作的需要。在有的单位,配备了几百台计算机,但是在高峰期,即便一千台电脑也远远不够用。而一旦设计结束,大量的电脑又会闲置无用。

  事实上,我们现在还没有实现资源层面的共享,只有信息的传输,所以会出现如此的“尴尬”。在理想的网格世界,成千上万台服务器的闲置时间可予以利用,可以租给需要大量计算能力的人。与对等网络、集群式超级计算机以及寻觅外星生命的SETI@home项目不同,网格计算的独特之处在于,能够允许多个用户同时工作,而非将所有计算能力集中于单一任务上。

  各领风骚二十年

  网格计算不是未来派的概念,它已经是实际的应用。加拿大平台计算公司首席技术官Songnian Zhou对于网格的前景十分看好。他认为:第一代处理方式(大型主机集中式处理)从上个世纪六十年代开始蓬勃发展了二十年,第二代计算模式(C/S模式)从上个世纪八十年代涌现至今也有了二十年。今天,我们已经看到,网格计算在商业界已经出现了一些成功的应用;尚处于起步阶段的网格计算这种企业信息系统第三代处理方式,估计也能至少使用20年。高端存储、分布式资源负载管理、协同工作、数据挖掘等领域,业已成为网格计算初试牛刀的战场。

  推动与制约

  软件和硬件产业的不断发展,让网格技术逐步完善,并走向现实;然而,网格思想的提出,也给软件和硬件产业提出严峻的挑战。

  实现信息服务网格应用的关键在于网格管理软件。网格管理软件在操作系统之上,可以看成是一种中间件。在应用网络化的时代,单机操作系统的地位已经降低,网格管理软件实际上是更高层次的网格操作系统,其核心技术主要是一体化的信息平台、语义网站、智能代理和知识本体等技术。

  网格技术的逐步成熟,存在几个主要的推动力量,分别是需求、技术和标准三个方面。

  需求:企业要求互联网应用要有非常强健的基础设施,比如可靠性、可伸缩性和安全性等。客户希望有多种的实现方式,无论是分布式、集中式,或者是客户自己要经营,或是外包经营,这些客户希望能够自己来决定。不但是这样,他们希望一旦作了决定之后,要从一个方式改到另一个方式是很容易的。现在,IT系统越来越复杂,如何使其管理成本降到最低呢?所有的这些使得网格计算的市场需求日益成熟。

  技术:从这十几年的发展来看,无论是CPU、存储、带宽都有非常大数量级的改进,跟十几年前不可同日而语。技术的发展已经能够让我们推动互联网进入到一个新的时代。

  标准:这是最重要的。分布在众多地点的不同计算资源要进行动态整合,节点之间的互操作不可避免,这就需要有一系列的标准协议和标准中间件去规范用户与资源之间的协同、建立、管理和挖掘共享关系。借助标准推行,以及协同与合作,互联网必将进入到网格的时代。

  当然,网格的发展还有很多制约因素。为了促进网格计算的广泛应用,实现让用户随心所欲地共享网格计算中的各种资源,还必须考虑以下问题:

  网格计算的兴起将改变传统的Client/Server和Client/Cluster结构,形成新的Pervasive/Grid(普适计算/网格计算)体系结构。在这种结构中,客户端是各种各样的上网设备,而连在网上的各种服务器将组成单一的逻辑上的网格(Grid)。

  在这种理念里,服务器的瓶颈不再是CPU和存储器,而是I/O子系统(I/O是输入输出的简称)——高性能的I/O子系统将是网格时代的一个主要研究方向。这是因为,在网格的应用中,由于信息资源的需求与供给都在动态变化而且分布在各个不同的位置,完成用户要求的一项服务可能要调用不同节点的服务器、数据库或者软件,因此对服务器的响应时间、网络的带宽。特别是网格管理软件的复杂性与灵活性以及网络上各种设备的互操作性都有很高的要求。

  此外,要进一步解决人机通信的问题,还要解决网格上资源共享中的知识产权问题,以及要保障网格计算的安全性。

Jul 6, 2008

对话框相关的话题

上次碰到一个问题
我要做A和B两个对话框,A为登陆,B为注册
实现的功能是A中若账号密码IP正确,点登陆,就能注销对话框进入主程序
若点A中的注册,则跳到B
若点A中的system menu里关闭按钮
则讲程序进程结束

对B而言,当填写注册资料验证无误后点注册
服务器接受数据并储存在数据库表单里后返回一个确认值及几个链表结构
则也注销对话框进入主程序,否则提示出错
若点B中的取消活着system menu的关闭
则返到A对话框

有一个问题
比如对于A,对话框的注销有三中情况
登陆成功,转到注册,关闭软件系统
而问题是按下Enter键后同样销毁了对话框(问题一)
这是因为它同样触发CDialog::OnOK虚函数处理OK键
而如何强制关闭当前进程??(问题二)
截取WM_CLOSE消息然后对三种情况用一个全局flag标志再在OnClose()函数里switch一下
这样也可以(现在想来)
不过我这里先给出当时我用的方法

首先截获WM_OK消息,将它的相应函数写为一个dummy function,即哑函数

void CLogIn::OnOK()//这里使用哑函数防止按下Enter就关闭对话框
{
//CLogIn是我写的登陆对话框类名
}

然后就先把退出软件系统这个功能解决了
即用户点A中关闭时,截获WM_CLOSE消息,处理函数如下

void CLogIn::OnClose() //当用户关掉登陆对话框,则进程结束
{
if(!isLogin)//m_socket与timer_socket是套接字部分,与本文无关
{
int end = 99;
send(m_socket,(char*)&end,sizeof(end),0);
send(timer_socket,(char*)&end,sizeof(end),0);
closesocket(m_socket);
closesocket(timer_socket);
}
m_pWnd=::GetCurrentProcess();//关键在这两个SDK函数
::TerminateProcess(m_pWnd,0);
}
然后解决登陆问题
void CLogIn::OnBtnLogin()
{
UpdateData(TRUE);
``` ``` ;//其他处理过程
CDialog::OnOK();
}
最后是跳到注册对话框问题
void CLogIn::OnBtnReg() //当用户选择注册时,调用注册对话框
{
UpdateData(TRUE);
CDialog::OnOK();
CRegister dlg;//CRegister是注册对话框类名
dlg.DoModal();
}

可以看到,Enter键的问题用哑函数解决了
而关闭系统进程的问题还有些有趣,连用两个SDK函数
其实还有一种做法,只有一句话,就是exit和_exit函数
在MSDN中对函数的说明如下
The exit and _exit functions terminate the calling process. exit calls, in last-in-first-out (LIFO) order, the functions registered by atexit and _onexit, then flushes all file buffers before terminating the process. _exit terminates the process without processing atexit or _onexit or flushing stream buffers. The status value is typically set to 0 to indicate a normal exit and set to some other value to indicate an error.

Although the exit and _exit calls do not return a value, the low-order byte of status is made available to the waiting calling process, if one exists, after the calling process exits. The status value is available to the operating-system batch command ERRORLEVEL and is represented by one of two constants: EXIT_SUCCESS, which represents a value of 0, or EXIT_FAILURE, which represents a value of 1. The behavior of exit, _exit, _cexit, and _c_exit is as follows.
可以直接一个exit(EXIT_SUCCESS)或exit(0)

这里之所以这么用是因为登陆对话框是在进入主程序前运行的
也就是说别的线程暂时还没有运行
如果此时别的线程(如监听线程等)已经运行
那么在OnClose()函数里要把所有该结束的线程也给结束了
比较麻烦
希望能找出一个快捷的方法

ListCtrl的删除功能(继续)

昨天写的那段删除功能代码今天调试时发现了个问题
表格的数据量不是很大,比如,只有4行的时候
刷新时还是会有闪烁的现象,很奇怪

我觉得可能是删除的时候按我写的那个循环
for(i=0;i{
DeleteItem(i);
}
变成每删除一个表格行就要刷一次屏幕,可能就是因为这样造成了闪烁
我要用这表格实现的功能是这样的
与服务器端通信,服务器每隔一定的时间间隔发送过来一个数据链表
客户端接收链表,解析后显示在表格里
这里就存在一个更新的问题,服务器的数据链表是动态变化的
而客户端这边的送显更新存在更新方式的问题

我原本想写个比较函数,比较下链表的不同,可是,这样的开销太大了
不仅是内存空间多花费,比较时间也是CPU开销啊
还不如直接删除原有item然后重新填充一下表格呢
昨天没有查MSDN,凭印象写了个DeleteItem(i)函数上去
今天查了下MSDN,原来还有个DeleteAllItems(),还不带参
一改下函数
果然不闪烁了

这才发现原来程序的世界里跟我们想的不同
越笨的方法可能越高效啊
谨记,谨记

Jul 5, 2008

ListCtrl的删除行功能

就一个小问题
我往表格里InsertItem
然后更新的时候我原先直接SetItemText
结果发现计算机没有删除原先的行,而是直接插入新行,把原有行往下移

单步调,把F10快给按烂了
没找到.感觉是对的啊
用于for循环里递进的i的值我一个个跟踪过去
是对的
靠,那是怎么回事

后来才发现,我按照常规的做法
for(i=0;i{
DeleteItem(i);
}
这是不对的
错在哪里呢???
错就错在M表格有一个自动缩进的功能,你删除了一个项
它自动缩进.
然后就发现问题所在了
表格项0对应记录1.当我第一次delete时delete掉了Item(0),也就是记录1
表格项1原先对应记录2,而第一次删除后自动缩进,变成对应记录3了
记录2则对应了表格项0;

ok,那我第二次deleteItem,是delete掉了Item(1),也就是记录3
好了,delete结束了,因为表格项2这回是空记录了(该死的,这里有溢出,可能溢出处理被封装了)
那这万恶的记录2就幸存了下来
继续由计算机往表格下端移动

Jul 4, 2008

一路走来(切题得一塌糊涂)

  有多少人还记得自己小时候学走路时一路的跌跌撞撞??
  我已经不记得了,或者是从来没有记起过,也正因为这样,我总认为既然我走路没有问题,当然我教人走路也没有问题;既然教人走路没有问题,那教机器人走路也一定没有问题。
  囧·····
  可是事实不是这样的····

  暑假终于是结束了,有机会可以回过头来认真的回想一下过去的点点滴滴。

  先介绍一下我们实验室的机器人。日本V-Stone公司的产品(没法子,日本人在机器人这方面确实做得很好),身上17个servomotor(17个自由度)分布是这样的。两条腿各5个,两条胳膊各3个,加个脑袋。整体来说这款humanoid robot还是比较出色的
   因为出色,所以·····难玩·····李博士就对我们说过,关节算法不是小本可以玩得起的~~~都是博士的课题······可是还是要调的,因为我们是小本,所以我们缺少谨慎的考虑因此我们有更多的创造力和韧性。因此很快的,李老大的那句不怎么振奋人心的话就被我们抛到脑后了。
   OH YEAH,大学的最后一个暑假就这样的开始了。


   由于机械组不知道舵机有初始位的(失误啊),所以他们都不给CPU Board上电就直接的把机器人组装好了。所以我们只好把原先装好的机器人重新大卸八块,挨个把舵机初始化好后装上去。这可是个苦差事啊。
   因为这是个仿人机器人,所以对加电后初始状态有很高的要求:脚掌舵机需为水平;小腿关节(x1),大腿关节(x2)这三个电机加电后必须保证转轴中心在一条垂线上;盆骨关节电机要求水平;手臂的标准难以测定,但是最低要求是所有手臂电机在极限位置不应该卡死,还要求两手臂对称···终于充分的认识到了标准的重要性,标准可以让以后的工作更好的开展。要不然,从一开始我们所面对的就是个畸形产物,就无法继续做下去,或者越做越糟糕。

   调整舵机的那段时间里真让人感觉是在地狱里走了一回,在崩溃的边缘挣扎(想象看,舵机的转轴上那么多密密麻麻的小齿)···舵机(servomotor)这玩意,太脆弱了,我相信负责调动作的四人小组里人人心里都会这么犯嘀咕。举例子来说吧:
   欧阳兄就上错了一个螺丝(M24上成M25),由于M25比较长,舵机自己卡住了,就那么几秒钟时间,一股青烟升起······囧······烧了·····拆开一看,电路板烧了·····
   CD兄正在调一个走路动作,抬起了左腿(重心已经移动到右腿了),就这么坚持了一会儿,他正在调两腿间距呢,突然间,又是一股青烟升起······囧·····又烧了······拆开一看,还是电路板上黑了一大块·····我们可爱的舵机啊······只有4个舵机备用,两天内就牺牲了一半了,这速度·····
   这时候我们才细细品味6月份到访的日本UEC Aoyama教授用英语想我们讲述的这段话,也是这时候我们才发现他说得真是太经典太生动了:Be careful when the robot walks . If you don't , some servomotors will burn out and you will find some smoke rise······
   小心小心再小心,舵机就是这么脆弱,一旦阻塞就容易发热,一旦发热,就要烧舵机的。舵机还是比较贵的,所以不可能尽情的烧的······烧的可都是人民币啊,这个想法一直延续至今·······我想对于实验室新招的那些成员,更是要强调这些。

   回到调试这里(顿时跳过了一段艰苦岁月进入一段相对少艰苦一点的岁月),终于把机器人弄得站起来了。加电后小家伙终于站起来了,RobotX到那时才正式出生呢。可是这小娃娃,只能站着,不会走路·····
   接下来,还没来得及喘口气,又开始新的征途,走路
   
   人是怎么样走路的呢?几个学生很激烈的讨论这个问题的场景实在很少见吧,而我们要弄清楚的正是这样一个已经被忽略了的问题。经过讨论我们制定的一套方案是:
   准备动作:先屈膝,重心前移一定距离,上身前倾
   走路动作:每次走路,应先把重心移动到一腿,抬起另一腿,前移,落下,重心移到该腿上,抬起原先重心所在腿,前移,落下,然后重复。
    制定了这个方案后我们还第一次认清了人原来不是走直线的啊,呵呵~~~~~

    方案总是越简单越实用越好,可是,实际做起来总是不断的有问题冒出来。
    按照我们的方案,出现了一个问题,就是,舵机承重时会有一定的偏移角,而这角度是因舵机而异的,所以,调整机器人走路时是绝对不对称的,而且,很不对称。另外一个问题是,走直线成了一件很难很难的事。人走路时是靠眼睛来修正路线的,而机器人只能靠走过一小段路后停下来调整方向,这样做还不如把走路和调整方向分开来得实际,所以我们前前后后做了很多个动作模块。前进,后退,左平移,右平移,大(小)角度左右转·······使用这些模块我们基本可以走到一个预期的地方,得到一个预期的站立姿态(因为还有下蹲取物的动作),不过终于是做完了。

    接下来就要开始联调了。九月底老板们要来看货了,要在那之前调好。不过,我们已经把所有动作做出来并调试过了,这回应该可以轻松一点了吧(重复了无数次的猜想)

   

Jul 3, 2008

The starting of my google blog life

Well .....
还是用中文比较舒服

这个博客是好不容易才知道该在哪申请的,哎
为了它我还更改了下语言设置

首先介绍一下我自己
一个热爱代码的狂人
一个有点执着的人
一个有耐心啃砖头的小学究

自称“键盘魔术师”
掌握C/C++/C#,平台有VC6.0,VS2005,ASP.NET2.0

OK,That's All. THX
Powered By Blogger