hur.cn - 华软网

 热门搜索

有人做过基于状态机的程序架构嘛!交流交流

  作者:未知    来源:网络    更新时间:2009/7/2
最近的一个运动控制项目,应用比较复杂。
特点如下:
1.数据比较多而且零散
2.无法清晰的将系统划分成独立的模块,这个和认识无关,控制系统里有控制耦合的概念,学控制的人知道
但是呢又需要系统中的模块有些时候需要独立处理,有些时候还必须从耦合的角度去处理多个模块
3.程式前一时刻的状态数据和后一时刻的数据相关,正常情况下我们前面执行的数据影响的是后面的,但是这个正好反过来了
前面数据处理还需要知道下一个数据是什么,但是这个时候程序还没有执行到下一条,所以还不知道是什么数据呢!呵呵所以这里肯定需要后台去处理一些事情。比如说我控制电机转180度,再反转90度,有可能要求电机转到135度的时候就开始减速了,所以有可能会有这样的要求:
move(a1,180);
move(a1,-90);
本质上并不是开线程就这么简单了,如果用通用的方法去做是不行的,因为要求是必须执行完第一句才执行第二句,这与现实相符
===========================================================
经过这些天我自己捉摸,始终无法想出很清晰很简单的办法,但是后来发现和OPENGL的需求很像,这个的确是可以用状态机来描述,但问题是我以前没有做过像状态机这种应用程序的框架,而且一般情况下我们要么是面向配方数据,要么是面对功能要求这种既要求配方数据又要求功能的的确是有些复杂
而且我怎么感觉设计模式里的东西怎么和状态机不靠边啊,我甚至硬套都套不进来啊
=====================================================
来大家谈谈想法


---华软 网友回答---
耦合是指:
同类型的模块按照某种规则叠加之后所得的新模型
这是我个人理解啊 
---华软网友回复---
呵,早就有人提出来了,可惜太笼统了
http://blog.csdn.net/vincent_lon/archive/2008/11/21/3344428.aspx
现实当中面向对象不一定是最锋利的武器哦
---华软网友回复---
设置模式中有一个state(状态)。 可以认为这就是状态机的一种。
再说了OO并不是万能的
---华软网友回复---
其实从本质上说报警检测也是状态机的一种
但是很显然当数据量过于复杂时还无法用它来处理
尤其是当把操作当成一种状态时它就不使用了
===============================================
坏老大,你对这种应用有什么看法嘛!
---华软网友回复---
没做过,支持
---华软网友回复---
按照这个来做。
http://www.zxbc.cn/html/20070710/24369.html
---华软网友回复---
定义一些状态,然后定义一些状态的响应,一个状态与一个状态响应注册为状态机的一个元素,在这元素之间转换就由状态机完成,当一个状态到来时,状态机会自动的就调用对应的响应。你程序设计的重心就落在了定义状态与实现状态响应上,流程设计起来也会简单,细节则状态机帮你处理了。
我们实现的就是通过链表与函数指针来管理状态与状态响应,大至的过程是这个样子:

FSM fsm;
fsm.add(StateA,CallBackA);
fsm.add(StateB,CallBackB);
fsm.add(StateC,CallBackC);

使用
fsm.GOTOSTATE(StateA);//实际上就调用CALLBACKA指向的过程
fsm.GOTOSTATE(StateB);
fsm.GOTOSTATE(StateC);

FSM里面记录有前一个状态,下一个状态等等信息。

不知道楼主要的是不是这样的东西。
---华软网友回复---
引用 6 楼 tkminigame 的回复:
按照这个来做。
http://www.zxbc.cn/html/20070710/24369.html

恩这个和我的需求很近了,谢谢
---华软网友回复---
感觉就是面向过程语言中GOTO语句的感觉,只是把它用面像对象的方式封装了一下
---华软网友回复---
像状态机这种,更像C语言等面向过程中处理比较方便,就是一个处理的过程,不停的转到下一个状态..
---华软网友回复---
引用 7 楼 breakind 的回复:
定义一些状态,然后定义一些状态的响应,一个状态与一个状态响应注册为状态机的一个元素,在这元素之间转换就由状态机完成,当一个状态到来时,状态机会自动的就调用对应的响应。你程序设计的重心就落在了定义状态与实现状态响应上,流程设计起来也会简单,细节则状态机帮你处理了。
我们实现的就是通过链表与函数指针来管理状态与状态响应,大至的过程是这个样子:

FSM fsm;
fsm.add(StateA,CallBackA);
fsm.add(StateB,…

说的好,但是你把数据和功能分开了,这个不行
因为要求是直接就执行,所以这个框架是不成立的,要求变成可预知的了
---华软网友回复---
执行当前动作时判断下一个动作,你将动作适当打包,总之只要动作总数是有限的,那么组合也是有限的。

---华软网友回复---
而且状态并不是离散的,它和编译原理的那个状态机并不相同
这个本质上执行的动作也是一种状态
比如说:
glBegin(GL_LINE_LOOP)
v1
v2
v3
v4
glEnd
这个很好办管理的就是队列,先入的先处理,咱们肯定能很简单的实现这个应用,但前提条件是得一个一个画完了才行,你才知道第四个点
但现在要求是你根据v2来操作v1的时候,应该如何组织程序结构
---华软网友回复---
引用 12 楼 jennyvenus 的回复:
执行当前动作时判断下一个动作,你将动作适当打包,总之只要动作总数是有限的,那么组合也是有限的。

对,肯定是需要打包处理,绝对不可能像表象那样,一条一条执行的
但是问题是如何打包,才能既思路清晰,还简单,以后还容易增加新的状态
---华软网友回复---
而且请大家注意,是由状态触发操作的,像那个减速过程
这个应当怎样处理
注意从框架设计的角度出发应当怎么做?
---华软网友回复---
引用 13 楼 dch4890164 的回复:
而且状态并不是离散的,它和编译原理的那个状态机并不相同
这个本质上执行的动作也是一种状态
比如说:
glBegin(GL_LINE_LOOP)
v1
v2
v3
v4
glEnd
这个很好办管理的就是队列,先入的先处理,咱们肯定能很简单的实现这个应用,但前提条件是得一个一个画完了才行,你才知道第四个点
但现在要求是你根据v2来操作v1的时候,应该如何组织程序结构

v2保存前后v1,v3的信息,每个状态都包含它所有分支..
---华软网友回复---
没做过
---华软网友回复---
引用 16 楼 oyljerry 的回复:
引用 13 楼 dch4890164 的回复:
而且状态并不是离散的,它和编译原理的那个状态机并不相同
这个本质上执行的动作也是一种状态
比如说:
glBegin(GL_LINE_LOOP)
v1
v2
v3
v4
glEnd
这个很好办管理的就是队列,先入的先处理,咱们肯定能很简单的实现这个应用,但前提条件是得一个一个画完了才行,你才知道第四个点
但现在要求是你根据v2来操作v1的时候,应该如何组织程序结构

v2保存前后v1,v3的信息,每个状态都包含…

那么,数据结构应当怎么组织呢,怎么建模呢
---华软网友回复---
哪位老大帮推荐的,谢谢非常感谢
---华软网友回复---
引用 7 楼 breakind 的回复:
定义一些状态,然后定义一些状态的响应,一个状态与一个状态响应注册为状态机的一个元素,在这元素之间转换就由状态机完成,当一个状态到来时,状态机会自动的就调用对应的响应。你程序设计的重心就落在了定义状态与实现状态响应上,流程设计起来也会简单,细节则状态机帮你处理了。
我们实现的就是通过链表与函数指针来管理状态与状态响应,大至的过程是这个样子:

FSM fsm;
fsm.add(StateA,CallBackA);
fsm.add(StateB,…

恩这个衍变一下,会很实用!呵呵谢谢
---华软网友回复---
引用 18 楼 dch4890164 的回复:
引用 16 楼 oyljerry 的回复:
引用 13 楼 dch4890164 的回复:
而且状态并不是离散的,它和编译原理的那个状态机并不相同
这个本质上执行的动作也是一种状态
比如说:
glBegin(GL_LINE_LOOP)
v1
v2
v3
v4
glEnd
这个很好办管理的就是队列,先入的先处理,咱们肯定能很简单的实现这个应用,但前提条件是得一个一个画完了才行,你才知道第四个点
但现在要求是你根据v2来操作v1的时候,应该如何组织程序结构

v2保存前…

类似与双向链表,前向,后向都可以转换
---华软网友回复---
关键是如何能把数据和操作分开,既一个是如何组织数据另外一个是如何响应动作流
==================================================================================
oyljerry恩谢谢,很值得参考,我会认真捉摸
==============================================
还有方法嘛
---华软网友回复---
呵呵其实再复杂的问题,最后都是用非常基础的方法去解决的!
有高手就是好啊!
---华软网友回复---
整个系统这一部分目前是我最不清晰的地方
---华软网友回复---
好东西,学习了!
---华软网友回复---
什么是状态机?
---华软网友回复---
en我也不知道到底该怎么才能 过这关。
---华软网友回复---
做控制用上位机控制?
---华软网友回复---
引用 7 楼 breakind 的回复:
定义一些状态,然后定义一些状态的响应,一个状态与一个状态响应注册为状态机的一个元素,在这元素之间转换就由状态机完成,当一个状态到来时,状态机会自动的就调用对应的响应。你程序设计的重心就落在了定义状态与实现状态响应上,流程设计起来也会简单,细节则状态机帮你处理了。
我们实现的就是通过链表与函数指针来管理状态与状态响应,大至的过程是这个样子:

FSM fsm;
fsm.add(StateA,CallBackA);
fsm.add(StateB,…

其实本质上这个描述只有状态转换,并没有涉及到动作
它的根本应用目的,比opengl的实现过程还要简单一些
opengl的框架肯定是把状态和操作分开了,都直接作用到底层的矩阵上了
---华软网友回复---
引用 28 楼 wozhaolala 的回复:
做控制用上位机控制?

呵呵以后的控制已经不分什么上位机下位机了
以后是我们程序员接手控制的时代了哈哈
---华软网友回复---
引用 13 楼 dch4890164 的回复:
而且状态并不是离散的,它和编译原理的那个状态机并不相同 
这个本质上执行的动作也是一种状态 
比如说: 
glBegin(GL_LINE_LOOP) 
v1 
v2 
v3 
v4 
glEnd 
这个很好办管理的就是队列,先入的先处理,咱们肯定能很简单的实现这个应用,但前提条件是得一个一个画完了才行,你才知道第四个点 
但现在要求是你根据v2来操作v1的时候,应该如何组织程序结构

根据v2操作v1,可以post一个状态变更的事件来操作
OnStateChanged(state)
{
  //更改操作行为
}

如果v1的操作行为是个线程,则通过线程间的数据定义来更改,例如
v1Thread(actionState)
{
  while not end
  {
    if (actionState == v2)...
    else ...
  }
}
---华软网友回复---
关注一下了....
---华软网友回复---
这个一定要关注一下。
---华软网友回复---
引用 29 楼 dch4890164 的回复:
引用 7 楼 breakind 的回复:

定义一些状态,然后定义一些状态的响应,一个状态与一个状态响应注册为状态机的一个元素,在这元素之间转换就由状态机完成,当一个状态到来时,状态机会自动的就调用对应的响应。你程序设计的重心就落在了定义状态与实现状态响应上,流程设计起来也会简单,细节则状态机帮你处理了。 
我们实现的就是通过链表与函数指针来管理状态与状态响应,大至的过程是这个样子: 

FSM fsm; 
fsm.add(StateA,C…

这个设计就是把状态与操作分开了,实际上GOTOSTATE就是调用某个状态对应的操作。这样做的好处是你不用关系操作是什么,操作与状态的对应在一开始就加入到状态机了,调用操作这件事交给状态机来完成。程序则集中在状态逻辑的处理。你只需要把状态衍变的关系理清楚了,程序就能正常的工作起来。
至于要实现怎么样的状态转换,这跟状态机的设计有关系,这里面能做到何种程序我也不清楚,因为我也就只做过我说的这种简单的东西。
---华软网友回复---
引用 34 楼 breakind 的回复:
引用 29 楼 dch4890164 的回复:
引用 7 楼 breakind 的回复:

定义一些状态,然后定义一些状态的响应,一个状态与一个状态响应注册为状态机的一个元素,在这元素之间转换就由状态机完成,当一个状态到来时,状态机会自动的就调用对应的响应。你程序设计的重心就落在了定义状态与实现状态响应上,流程设计起来也会简单,细节则状态机帮你处理了。
我们实现的就是通过链表与函数指针来管理状态与状态响应,大至的过程是这个样子…

恩你说的对,用的是回调函数,我没有理解清楚
这个方法的确是很好,我有些清楚了!呵呵
而且这个也确实好扩展
动作和数据也分开了,但是它还是没有解决状态相关的问题,即需要结合下一个状态,执行相应的操作

---华软网友回复---
如果能把您的方法和oyljerry老大的想法结合到一起就好了!
---华软网友回复---
引用 7 楼 breakind 的回复:
FSM fsm;
fsm.add(StateA,CallBackA);
fsm.add(StateB,CallBackB);
fsm.add(StateC,CallBackC);

使用
fsm.GOTOSTATE(StateA);//实际上就调用CALLBACKA指向的过程
fsm.GOTOSTATE(StateB);
fsm.GOTOSTATE(StateC); 

这个所有的状态都是独立的,和opengl的操作差不多啊
---华软网友回复---
引用 36 楼 dch4890164 的回复:
如果能把您的方法和oyljerry老大的想法结合到一起就好了!

所以说具体的实现取决于状态机的设计,这方面的东西太高深了,没研究过,呵呵。
---华软网友回复---
引用 38 楼 breakind 的回复:
引用 36 楼 dch4890164 的回复:
如果能把您的方法和oyljerry老大的想法结合到一起就好了!

所以说具体的实现取决于状态机的设计,这方面的东西太高深了,没研究过,呵呵。

你现在不是有机会再研究嘛哈哈
============================================
恩我现在已经感觉到自己有点摸到门了
---华软网友回复---
引用 30 楼 dch4890164 的回复:
引用 28 楼 wozhaolala 的回复:

做控制用上位机控制? 

呵呵以后的控制已经不分什么上位机下位机了 
以后是我们程序员接手控制的时代了哈哈


同感,
现在的控制居然有用Java做的,而且是价值数百上千万的设备。

个人感觉你的设计思路上有点问题
状态是被动的是用来查询的,是由一个或一系列动作触发的,这样控制权在你手中,不至于丢失控制而面临尴尬的局面。
如果是状态触发一个或一些动作,简单的还可以,相对复杂一些的根本就是灾难。就拿简单的DI来说,实现也很复杂。

动作与数据分离设计模式有很好的案例可借鉴。

---华软网友回复---
引用 40 楼 zhoujianhei 的回复:
引用 30 楼 dch4890164 的回复:
引用 28 楼 wozhaolala 的回复:

做控制用上位机控制?

呵呵以后的控制已经不分什么上位机下位机了
以后是我们程序员接手控制的时代了哈哈


同感,
现在的控制居然有用Java做的,而且是价值数百上千万的设备。

个人感觉你的设计思路上有点问题
状态是被动的是用来查询的,是由一个或一系列动作触发的,这样控制权在你手中,不至于丢失控制而面临尴尬的局面。
如果是状态触发一个…

老大你反过来看啊,状态也是可以被控制的啊
呵呵给点想法
=============================================================
是啊,的确是有用JAVA做控制的,呵呵还有用C#做组态软件的呢!

---华软网友回复---
opengl就是基于状态机的架构,这个我是在官方文档上看的
http://www.opengl.org/documentation/specs/version2.0/glspec20.pdf
17页 our view节 下面的那句话

---华软网友回复---
其实很难说是状态触发了操作,还是操作改变了状态
====================================================
关键是这玩艺怎么把它隔离开?比较烦
有点感觉又好像没什么感觉
---华软网友回复---
引用 41 楼 dch4890164 的回复:
引用 40 楼 zhoujianhei 的回复:
引用 30 楼 dch4890164 的回复:
引用 28 楼 wozhaolala 的回复:

做控制用上位机控制?

呵呵以后的控制已经不分什么上位机下位机了
以后是我们程序员接手控制的时代了哈哈


同感,
现在的控制居然有用Java做的,而且是价值数百上千万的设备。

个人感觉你的设计思路上有点问题
状态是被动的是用来查询的,是由一个或一系列动作触发的,这样控制权在你手中,不至于丢失控制而面临…
但是,实际上进行控制的是plc,plc是可靠的,
---华软网友回复---
引用 44 楼 wozhaolala 的回复:
但是,实际上进行控制的是plc,plc是可靠的,

扯远啦,但是plc只适合于逻辑处理,复杂的计算它就不行了
===========================================================
呵呵,如果大家乐意我哪天另开一贴,今天还是先讨论一下我现在的问题比较好

---华软网友回复---
引用 41 楼 dch4890164 的回复:
老大你反过来看啊,状态也是可以被控制的啊 
呵呵给点想法 
============================================================= 
是啊,的确是有用JAVA做控制的,呵呵还有用C#做组态软件的呢! 


那为什么不直接读取状态进行判断后再执行动作呢?
至于用Java做控制,个人认为不是不可以,符合实际需要就可以,只是没想到发展的这么快。
C#做组态,感觉没那么紧张,又不是什么控制,要求也不高。

---华软网友回复---
引用 46 楼 zhoujianhei 的回复:
引用 41 楼 dch4890164 的回复:
老大你反过来看啊,状态也是可以被控制的啊
呵呵给点想法
=============================================================
是啊,的确是有用JAVA做控制的,呵呵还有用C#做组态软件的呢!


那为什么不直接读取状态进行判断后再执行动作呢?
至于用Java做控制,个人认为不是不可以,符合实际需要就可以,只是没想到发展的这么快。
C#做组态,感觉没那么紧张,又不是什么控制,要求也不高…

关键是原理上一次读一个这个好做,一次读俩,单独就处理这种情况还行,但是以后麻烦了
还有就是有隐含条件怎么办,如需要减速的那个条件,怎么样能让这些都自动化处理
=================================================================================
呵呵谁说组态要求不高,哪个组态软件没有实时库,但据我所知,用c#写的组态软件好像是没有实时库
---华软网友回复---
现在操作的组织,和数据的组织对不上啊、
没有办法都隔离
---华软网友回复---
关键是根据条件来判断,这种硬编码的方式,以后改起来会很麻烦
---华软网友回复---
引用 47 楼 dch4890164 的回复:
关键是原理上一次读一个这个好做,一次读俩,单独就处理这种情况还行,但是以后麻烦了 
还有就是有隐含条件怎么办,如需要减速的那个条件,怎么样能让这些都自动化处理 
================================================================================= 
呵呵谁说组态要求不高,哪个组态软件没有实时库,但据我所知,用c#写的组态软件好像是没有实时库


电机控制有很多算法,实际上就是模拟曲线运动,这跟状态有什么关系呢。
组态软件?谁能给个标准的定义?      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。