用这个拿了4个创新学分
星期一 04月 20th 2009, 20:03
归类于:
未分类
实时电梯群控制仿真系统的设计与实现学生研究总结报告
——————自动化2006级3班 范国恒(200630511277)
一、研究过程
时间 | 内容 | 备注 |
2008年4月 | 许老师召开会议,对我们做了c++知识的要求,向我们提示了电梯群控模型建立的内容与逻辑方式。 | 讨论完毕之后,我们各自回去进行c++学习。 并且做了电梯群控模型的逻辑构思。 |
2008年6月 | 许老师召开会议,帮助我们解决前两个月中c++学习遇到的问题。并继续给予我们建立电梯群控模型的建议。 | 会议完毕之后,我们各自回去继续进行c++深入学习。 并且继续进行电梯群控模型的逻辑构思。 |
2008年8月 | 暑假期间学习c++ | 我读了Harvey and Paul Deitel’s 《C++ How to Program》,进行了c++的自主学习。 |
2008年10月 | 进行电梯群控运行逻辑的通俗语言描述。 | 我进行了电梯群控运行逻辑的通俗语言描述的文档撰写,详情见“三、研究成果”。 |
2008年12月 | 许老师召开会议,检验我们的c++学习成果以及电梯群控模型建立情况。 | 我们进行了c++问题的沟通和电梯群控模型逻辑的讨论,取得了初步的统一。并且进行代码编写的分工,由我主要建立各部分的头文件以及一些源文件的编写,由陈帝水师兄进行另一部分的源文件编写。 |
2009年2月 | 我们自己对自己编写的源代码进行剖析与检验。 | 许老师也给我们一些建议,但是我们发现我们的基础知识不够,不能很好地完成代码的编写。 |
2009年4月 | 许老师带领我们进行项目总结。 项目结题。 | 虽然我们努力了,进行了电梯群控模型的逻辑构思,并且也进行了实际代码的编写。但是由于我们编程能力不足,项目经验太少,导致这次项目没有能够完整地编撰出符合要求可以运行的实际程序。 不过,我们在其中也学到了很多东西,无论是c++语言上的,还是对客观事物进行建模上的。我们都收获颇多。 |
二、研究总结
经过一年的项目研究,在许老师的带领下,我系统完整地学习了c++这门语言,并且从观察现实世界开始,进行了对现实世界中电梯群控现象的模拟。虽然到最后我们没有能够完成完整的程序编写,但是,我觉得我收获很多。我们也建立了“电梯群控逻辑实现”,同时完成了一定量的程序代码编写。
在c++学习方面,我有以下心得体会。
1、事必躬行。我刚开始只是看书不动手。但是,语言和平台有关,任何平台都不是绝对支持标准。大学C++老师开始上课就告诉我们了这个秘诀,而听取得人不多。对于一个初学者来说,熟悉语法、锻炼手感和培养思维最好得办法就是编程,照着书上直接敲代码。编译后,对代码进行思考,我发现了很多问题,解决问题的同时我有了提高。
2、不耻上问。我刚开始学习的时候碍于面子,不敢问问题。现在发现完全没有必要。后来,我找了一个c++技术过关,而且容易交流的同学作为我的c++学习老师。
3、尽善尽美。山外有山,人外有人,多学习别人先进经验,严格要求自己,追求完美,尽管完美追不到,至少有提高。
在建立电梯群控模型上,我有以下心得体会:
第一,选择要创建什么模型,对如何动手解决问题和如何形成解决方案有着意义深远的影响。
换句话说,就是要好好地选择模型。正确的模型将清楚地表明最棘手的开发问题,提供不能轻易地从别处获得的洞察力;错误的模型将使人误入歧途,把精力花在不相关的问题上。
暂时先把软件问题放在一边,如果建立了一个物理模型,并去实验,虽然小模型没有精确地反映出大的实物,但也可以从中找出一些有趣的东西。因此,如果正在建立一个数学模型,然后去模拟,将知道一些不同的东西;与使用物理模型相比,也可能获得更多新的场景。通过对模型进行严格的持续的实验,将更信任已经建模的系统,事实上,它在现实世界中将像期望的那样工作得很好。
对于软件而言,所选择的模型将在很大程度上影响对领域的看法。如果以数据库开发者的观点建造一个系统,可能会注意实体—联系模型,该模型把行为放入触发器和存储过程中。如果以结构化开发者的观点建造一个系统,可能得到以算法为中心的模型,其中包含从处理到处理的数据流。如果以面向对象开发者的观点建造一个系统,将可能得到这样一个系统:它的体系结构以一组类和交互模式(指出类如何一起工作)为中心。可执行的模型对测试有很大帮助。上述的任何一种方法对于给定的应用系统和开发文化都可能是正确的,经验表明,在构建有弹力的体系结构中面向对象的方法表现得更为出众,即使对使用大型数据库或计算单元的系统也是如此。尽管事实如此,但要强调一点,不同的方法将导致不同种类的系统,并且代价和收益也是不同的。
比如这次电梯群控模型的建立,我就没有模拟电梯的灯以及响铃这些具体的细节,因为它对于达到我们控制目的没有帮助。
第二,可以在不同的精度级别上表示每一种模型。
比如这次电梯群控模型的建立,刚开始的时候我考虑地很细致。企图一丝不差的模拟现实世界,包括人流的情况,包括电梯的调度等等。但是发现建立了复杂的模型,必须用大量的代码去实现,然而,对于我们需要求得的模拟结果并不一定有很强劲的帮助。所以,后来我就简化了模型,但是这种简化建立在不会影响模型模拟现实,得出合理结果的基础上。
对于软件模型也是如此。有时一个快速简洁且是可执行的用户界面模型正是所需要的,而有时必须耐着性子对付比特,例如,描述跨系统接口或解决网络瓶颈问题就是如此。在任何情况下,最好的模型应该是这样的:它可以让你根据谁在进行观察以及为什么要观察选择它的详细程度。分析人员或最终用户主要考虑“做什么”的问题,开发人员主要考虑“怎样做”的问题。这些人员都要在不同的时间以不同的详细程度对系统进行可视化。
第三,最好的模型是与现实相联系的。
如果建筑的物理模型不能以与真实的建筑相同的方式做出反应,则它的价值是很有限的;飞机的数学模型,如果只是假定了理想条件和完美制造,则可能掩盖真实飞机的一些潜在的、致命的现实特征。最好是有能够清晰地联系实际的模型,而当联系很薄弱时能够精确地知道这些模型怎样与现实脱节。所有的模型都对现实进行了简化;但有一点要记住,关键是简化不要掩盖掉任何重要的细节。
软件领域中结构化分析的致命弱点是在分析模型和系统设计模型之间没有基本的联系。随着时间的推移,这个不可填充的裂缝会使系统构思阶段和实施阶段出现不一致。在面向对象的系统中,可以把各个几乎独立的系统视图连结成一个完整的语义整体。
第四,单个模型或视图是不充分的。对每个重要的系统最好用一小组几乎独立的模型从多个视角去逼近。
如果正在建造一所建筑物,会发现没有任何一套单项设计图能够描述该建筑的所有细节。至少需要楼层平面图、立面图、电气设计图、采暖设计图和管道设计图。并且,在任何种类的模型中都需要从多视角来把握系统的范围(例如不同楼层的蓝图)。
在这里的重要短语是“几乎独立的”。在这个语境中,它意味着各种模型能够被分别进行研究和构造,但它们仍然是相互联系的。如同建造建筑物一样,既能够单独地研究电气设计图,但也能看到它如何映射到楼层平面图中,以及它与管道设计图中的管子排布的相互影响。
面向对象的软件系统也如此。为了理解系统的体系结构,需要几个互补和连锁的视图:用况视图(揭示系统的需求)、设计视图(捕获问题空间和解空间里的词汇)、交互视图(展示系统各部分之间以及系统与环境之间的联系)、实现视图(描述系统的物理实现)和部署视图(着眼于系统的工程问题)。每一种视图都可能有结构方面和行为方面。这些视图一起从整体上描绘了软件蓝图。
根据系统的性质,一些模型可能比另一些模型要重要。例如,对于数据密集型系统,表达静态设计视图的模型将占主导地位;对于图形用户界面密集型系统,静态和动态的用况视图就显得相当重要;在硬实时系统中,动态进程视图尤为重要;最后,在分布式系统中,例如Web密集型的应用,实现模型和部署模型是最重要的。
三、研究成果
(一)实时电梯群控制仿真系统的设计与实现逻辑分析报告(如下)
实时电梯群控制仿真系统的设计与实现
一、需求陈述
1.为含群梯的大楼系统建模,包括中央控制器、楼层、电梯、乘客等。模型模拟在不同群控策略和用梯需求下,大楼的运行情况。观察结果,验证群控策略的合理性。
2.大楼模型与群控策略、大楼模型与用梯需求都独立无关:群控策略及用梯需求可在模型中自由实现,不受模型限制(模型中内置默认的策略及用梯需求)。
3.模型可调整、可扩展,以适应更高的模拟需求。比如,为乘客加入心情指数,为电梯加入磨损指数,使中央控制器具有超前决策功能等。
4.程序是封装的,为实现对群控决策和用梯需求的不同模拟而对外提供接口,但不暴露内部实现。
5.其他:为程序创建可视化界面(对参数的修改,显示大楼的运行情况);内置多种策略和用梯需求。
二、基于需求的模拟
1.系统概述:一栋大楼有N部电梯,M层楼层;一个中央控制器对电梯进行群控;一个乘客创建器创建乘客,模拟乘客流量。
2.电梯相邻性:共N部电梯,默认为其中相邻编号的电梯的地理位置相邻(1号与2号相邻,N号与N-1号相邻)。
相邻性可调整,但每部电梯最多有3部电梯与之相邻,没有显式指定相邻性的电梯默认为号码差越小的电梯越相邻。电梯相邻性可去掉。
3.群控与自控:系统模拟运行时可设置两种状态:群控状态下,电梯完全由中央控制器群体控制;自控状态下,电梯自我控制,各电梯信息互不相通。
4.乘客:
注:每一楼层为每部电梯都设置了楼层按钮。当乘客被创建时,会选择其中一部电梯进行召唤,然后等候在此部电梯门口。这部电梯对于这位乘客来说是“本部电梯”,而其他电梯对于他来说是“异部电梯”。乘客只要所在楼层有电梯可乘,就会搭乘电梯。
1)待电梯内乘客全部离开电梯后,楼层中的乘客才进入电梯。
2)进入电梯的优先权依次是:先召唤本部电梯的乘客>后召唤本部电梯的乘客>先召唤异部电梯的乘客>后召唤异部电梯的乘客。当电梯满员后(默认为13人满员),乘客停止进入电梯。
3)乘客召唤电梯后,一直等待电梯,不会中途离开。
4)乘客一旦被创建,就有了目的地楼层,并且不会变更。
5)乘客是理智的,目的地是楼上的乘客不会进入一部向下行进的电梯。
5.时间:模型中时间最小分度为1秒。
1)乘客一旦被创建,立即按下楼层按钮召唤电梯,到达目的地后结束生命。乘客进入电梯后按下电梯按钮不花时间。
2)电梯门开关都需要1秒钟。不模拟楼层门,认为它随电梯门自动启闭。电梯开门后至少2秒才会关门(即使没有乘客出入)。
3)电梯移动到相邻楼层默认需要5秒。(对外提供接口,可调整)
4)乘客进入或离开电梯时间默认为下表:
人数(人) | 时间(秒) | 人数(人) | 时间(秒) |
1~2 | 2 | 7~8 | 8 |
3~4 | 4 | 9~10 | 10 |
5~6 | 6 | 11~13 | 12 |
(对外提供接口,可调整)
6.默认的群控策略和用梯需求:
1)群控策略:用户至上。
2)用梯需求:均匀需求。
三、逻辑(群控时)
作用于模型,使之运行的两个因素:时间与消息的传递。
设立一个时钟,独立地流走时间。模型其他部分都直接或者间接地从“时钟”上获取时间,以确定自己的行为与状态。在1秒以内,各部分完全完成自己这一秒的行为并留下一个确定的状态。在1秒末时刻,取一个时间切片,观察整个模型的状态,作为模型这一秒的运行数据。也以此刻为标记,完成1个周期(1秒)的模拟。
模型的一个周期(1秒):
1.中央控制器
1)消息收集器:收集消息放入消息暂存器。
2)消息暂存器:(暂存内容)
①各楼层按钮被先后置下的次序。
②电梯所在楼层,运行状态(移动、进出乘客等待或闲置),电梯是否满载。
③梯内按钮被置下的情况。
3)消息处理器:处理消息暂存器内的消息,形成命令,按照命令的优先权顺序放入命令暂存器,删除处理过的消息。
4)命令暂存器:电梯在某段时间内的命令,按命令被执行的先后排序。
5)命令发送器:在上一条命令完成后,删除这条命令。把下一条命令发送到电梯中,并把这条命令置于命令暂存器的首端。//把优先权更高的命令直接发送给电梯,中止正在进行的命令。
中央控制器的一个周期(1秒):
2.乘客创建器:①按照事先给定的规律创建乘客,分配到各个楼层的各电梯门前召唤电梯。创建第一个乘客的编号为0,依次往后编号,不使用已使用过的号码。
②乘客创建器中只保存“存在”的人的信息,被销毁的乘客数据不保存。
③提供对外接口,提供完全自由的用梯需求创建。
乘客创建器示意图:
3.楼层:①接受乘客创建器创建的乘客。
②暂存乘客的呼梯申请。
③接受中央控制器查看呼梯需求。
④在电梯控制下传送乘客到电梯内部。
⑤向电梯提供楼层的状态信息。
注:楼层没有主动行为,由其他部分驱动它完成任务。
4.电梯:
电梯的一个周期:
①保存自身状态,供中央控制器查阅。
②保存乘客进入梯内后的用梯需求,供中央控制器查阅。
③暂存中央控制器发送给它的一条立即(正在)执行的命令。
④移动,以响应自身命令暂存器中的命令。
注:中央控制器对电梯的命令仅仅指示电梯移动的目的地。当移动发生后,电梯按照自己内置流程完成余下的工作:移动、到达目的地后开门、至少2秒后关门。中途接收到另一条命令也仅仅是目的地的更改。
电梯必须执行中央控制器的命令。若当电梯向上移动的时候,中央控制器发送给它向下的命令。电梯会自动预设一个向上到达最近楼层的命令,执行后,执行中央控制器的向下命令。
⑤控制楼层运送乘客进入电梯。
⑥删除出电梯的乘客。
⑦告知中央控制器,自己已经完成一条命令。
5.乘客:①按下楼层按钮召唤电梯。
②被电梯置入电梯内部,按下电梯按钮。
③通知乘客创建器,自己已被删除。
6.时钟:为其他各部分提供时间。
7.运行显示器:每秒钟查看中央控制器和乘客创建器中保存的信息,并显示为电梯运行情况。
包括:①电梯的状态(移动、闲置或正在出入乘客)。
②电梯所在的楼层。
③电梯中的人数。
④楼层中的候梯人数及他们的目的地。
<自控运行时的更改>
电梯的一个周期:
模型的一个周期:
(二)源代码(如下)
1.building.cpp
#include “building.h”
Building::Building(int M,int N){
for(int i=1;i<=M;i++)
floorBox.push_back(new Floor);
for(int j=1;j<=N;j++)
elevatorBox.push_back(new Elevator);
floorIterator=floorBox.begin();
elevatorIterator=elevatorBox.begin();
}//初始化M层楼层和N部电梯,指向第一层楼的迭代器,指向第一部电梯的迭代器
Building::~Building(){
for(floorIterator=floorBox.begin();
floorIterator=floorBox.end();
floorIterator++)
delete (*floorIterator);
for(elevatorIterator=elevatorBox.begin();
elevatorIterator=elevatorBox.end();
elevatorIterator++)
delete (*elevatorIterator);
}//删掉用new创建的楼层指针和电梯指针,释放内存
Building::runSimulation(int duration){
int currentTime=1;
while(currentTime<=duration){
pC.run();
cC.run();
elevator.run();//模型总体的流程:创建乘客-中央控制器处理信息,形成命令-电梯处理命令,形成指令,执行指令-(循环)
}
}
2.floor.cpp
#include “floor.h”
Floor::Floor():floorRequest(no){
passengerIterator=passengerBox.end()–;
}
Floor::~Floor(){
for(floorBoxIterator=floorPassengerBox.begin();
floorBoxIterator=floorPassengerBox.end();
floorBoxIterator++)
delete (*floorBoxIterator);
}
FloorRquest Floor::getFloorRequest(){
rutern floorRquest;
}
void Floor::getPassenger(passenger* newPassenger){
passengerBox.push_back(newPassenger);
setFloorRequest(newPassenger.gerFloorRequest());
}
passenger* Floor::deliverPassenger(){
Passenger temp;
if(!passengerBox.empty())
temp=*(passengerIterator);
if(passengerIterator!=passengerBox.begin())
passengerIterator–;
return temp;
}
3.main.cpp
//主程序,设定楼层数,电梯数,模拟时间,启动模拟
#include <iostream>
using std::cout;
using std::endl;
#include “building.h”
int main()
{
int duration;
int M;
int N;
cout<<”How many floors: “;
cin>>M;
cout<<”How many elevators: “;
cin>>N;
cout<<”Enter run time(s): “;
cin>>duration;
cin.ignore();
Building building(M,N);
cout<<”*** ELEVATOR GROUP SIMULATION BEGINS ***”<<endl
<<endl<<endl;
building.runSimulation(duration);
cout<<”*** ELEVATOR GROUP SIMULATION ENDS ***”<<endl;
return 0;
}
4.building.h
//大楼的头文件
#ifndef BUILDING_H
#define BUILDING_H
#include <vector>
using namespace::std;
#include “floor.h”
#include “passengerCreator.h”
#include “centralControl.h”
#include “elevator.h”
class Building {
public:
Building(int M,int N);
~Building();
void runSimulation(int duration);
private:
vector<Floor*> floorBox;//装楼层指针的容器
vector<Elevator*> elevatorBox;//装电梯指针的容器
vector<Floor*>::iterator floorIterator;//指向楼层容器的迭代器
vector<Elevator*>::iterator elevatorIterator;//指向电梯的迭代器
CentralControl cC;//中央控制器
PassengerCreator pC;//乘客创建器
};
#endif
5.floor.h
//楼层头文件
#ifndef FLOOR_H
#define FLOOR_H
#include <vector>
using namespace::std;
#include “passenger.h”
enum FloorRequest{no,up,down,upDown};
//枚举类型的楼层呼梯请求,no是没有呼梯请求,up仅有向上的呼梯请求,down仅有向下的呼梯请求,upDown是向上向下的呼梯请求均有
class Floor {
public:
Floor();
~Floor();
void getPassenger(passenger* newPassenger);//乘客创建器把乘客送入电梯
FloorRequest getFloorRequest();//中央控制器获得呼梯请求
passenger* deliverPassenger();//电梯从楼层获得乘客
private:
vector<passenger*> passengerBox;//乘客盒子,用于装乘客指针
vector<passenger*>::iterator passengerIterator;//乘客盒子的迭代器,用于使用乘客盒子
FloorRequest floorRequest;//存储呼梯请求
void setFloorRequest(FloorRequest floorRequest);//设定呼梯请求
void resetFloorRequest();//重设呼梯请求
};
#endif