Qt5编写的电梯控制模拟程序 附源码
- 图
- 源代码链接地址:
- 系统架构
- 逻辑实现
- elevator.h
- elevaotr.cpp
- 未完待续、、、
用c++和qt5编写的单电梯模拟程序
简介:这是一个在Qt5中构建的小型电梯模拟程序。包括门控和电梯升降控制。因为我在其中使用win32 api, MSVC应该是构建的选择。目前,它仍然存在一个小bug,它总是由最近的呼叫面板信号引起的。还有一件事,当系统准备好启动时,必须首先单击启动按钮,否则将发生意外的错误。
图
开机图:
启动图:
源代码链接地址:
GitHub源代码链接:Elevator-Simulation
Elevator-Simulation
This is an small elevator-simulation program builded in Qt5. Contains door control and elevator up-down control. Since I’m using win32 api in it, the MSVC should be choice for build. For now, a small bug is still exists in it which is always caused by nearest out-call panel signal. One more thing, you must click the Starting up button at first when system is ready for starting, otherwise a unexpected error will be happen.
构建说明
第一步:新建你的Qt项目
第二步:删除项目所有.cpp和.h和.ui文件
第三步:将.h添加进你项目中的Headers(注:头文件),将.cpp添加进你的Sources(源文件),将.ui文件添加进你的Forms(界面)中。
第四步:构建你的项目并运行
第五步:点击开机按钮,开始体验模拟电梯吧
系统架构
采用前后分离
电梯的状态机和控制系统分离
qt界面和电梯逻辑分离
逻辑实现
编写步骤:
第一步,在vs上编写纯逻辑实现核心代码:elevaotr.cpp和elevator.h
第二部,编写Qt5适配器,做可视化和接受控制信号:QtAdapter.h
状态机组成:
状态机由门和电梯两部分组成,实时扫描外界面板控制信号和内派信号。
具体画的状态机转换图纸在家放着,有时间补上
核心代码1:
elevator.h
#ifndef ELEVATOR_H
#define ELEVATOR_H
#include <QMainWindow>
#include<QObject>
#include<Windows.h>
#include<stdio.h>
#include<string.h>
#define LEVEL 6
enum eDoorState
{
OPEN=1,
CLOSE,
LOCK,
OPENING,
CLOSING,
};
enum eElevatorState
{
STOP=1,
UP,
DOWN
};
enum eDoorButton
{
NONE=0,
OPENDOOR,
CLOSEDOOR
};
enum eElevatorDirection
{
LIFT=1,
DROP,
SUSPEND
};
struct ElevatorHight
{
ElevatorHight():nowHight(0), levelHigh(1000) ,fullLevel(LEVEL) , moveSpeed(5){}
int nowHight;
const int levelHigh;
const int fullLevel;
const int moveSpeed;
};
struct DoorWidth
{
DoorWidth() :nowWidth(0), fullWidth(1000),openSpeed(5),waitTime(100){}
int nowWidth;
const int fullWidth ;
const int openSpeed ;
const int waitTime;
};
class Elevator : public QObject
{
public:
char floorDownList[LEVEL];
char floorUpList[LEVEL];
char panelButtonList[LEVEL];
enum eDoorState doorState;
enum eElevatorState elevatorState;
enum eDoorButton doorButton;
enum eElevatorDirection liftDirection;
struct ElevatorHight elevatorHight;
struct DoorWidth doorWidth;
Elevator();
private://行为
void doorClose();
void doorLock();
void doorOpening();
void doorClosing();
void doorOpen();
void liftStop();
void liftUp();
void liftDown();
private:
static DWORD WINAPI doorThread(void* p);
static DWORD WINAPI elevatorThread(void* p);
};
#endif
附核心代码2:
elevaotr.cpp
#include "elevator.h"
#include<QDebug>
#define HZ 10
Elevator::Elevator()
{
doorButton = NONE;
doorState = CLOSE;
elevatorState = STOP;
liftDirection = SUSPEND;
doorWidth.nowWidth = 0;
elevatorHight.nowHight = 0;
memset(floorDownList, 0, sizeof(floorDownList));
memset(floorUpList, 0, sizeof(floorUpList));
memset(panelButtonList, 0, sizeof(panelButtonList));
CreateThread(NULL, 0, doorThread, this, 0, NULL);
CreateThread(NULL, 0, elevatorThread, this, 0, NULL);
}
void Elevator::doorClose()
{
while (doorState == CLOSE)
{
if (doorButton == OPENDOOR)
{
doorState = OPENING;
return;
}
if ((elevatorState == UP) || (elevatorState == DOWN))
{
doorState = LOCK;
return;
}
if (doorButton == CLOSEDOOR)
{
doorButton = NONE;
}
Sleep(HZ);
}
}
void Elevator::doorLock()
{
while (true)
{
if (elevatorState == STOP)
{
doorState = OPENING;
return;
}
Sleep(HZ);
}
}
void Elevator::doorOpening()
{
while (true)
{
if (doorWidth.nowWidth < doorWidth.fullWidth)
{
doorWidth.nowWidth += doorWidth.openSpeed;
}
if (doorWidth.nowWidth == doorWidth.fullWidth)
{
if (doorButton == OPENDOOR)
doorButton = NONE;
doorState = OPEN;
return;
}
if (doorButton == CLOSEDOOR)
{
doorState = CLOSING;
return;
}
Sleep(HZ);
}
}
void Elevator::doorClosing()
{
while (true)
{
if (doorState == CLOSING)
{
doorWidth.nowWidth -= doorWidth.openSpeed;
}
if (doorWidth.nowWidth == 0)
{
doorState = CLOSE;
return;
}
if (doorButton == OPENDOOR)
{
doorState = OPENING;
return;
}
Sleep(HZ);
}
}
void Elevator::doorOpen()
{
int delay = doorWidth.waitTime;
while (delay > 0)
{
if (doorButton == CLOSEDOOR)
{
doorState = CLOSING;
return;
}
if (doorButton == OPENDOOR)
{
delay = doorWidth.waitTime;
continue;
}
delay--;
Sleep(HZ);
}
doorState = CLOSING;
if (doorButton == OPENDOOR)
{
doorButton = NONE;
}
}
DWORD WINAPI Elevator::doorThread(void* p)
{
Elevator *elevator = (Elevator*)p;
while (true)
{
switch (elevator->doorState)
{
case CLOSE:
elevator->doorClose();
break;
case LOCK:
elevator->doorLock();
break;
case OPENING:
elevator->doorOpening();
break;
case CLOSING:
elevator->doorClosing();
break;
case OPEN:
elevator->doorOpen();
break;
}
Sleep(1);
}
return 0;
}
void Elevator::liftDown()
{
int level;
do {
elevatorHight.nowHight -= elevatorHight.moveSpeed;
level = elevatorHight.nowHight / elevatorHight.levelHigh;
int i;
for (i = level; i >0; i--)
{
if ((floorDownList[level] == 1) || (panelButtonList[level] == 1))
{
break;
}
}
if (elevatorHight.nowHight % elevatorHight.levelHigh == 0)
{
if ((floorDownList[level] == 1) || (panelButtonList[level] == 1))
{
floorDownList[level] = 0;
panelButtonList[level] = 0;
elevatorState = STOP;
return;
}
if (i == elevatorHight.fullLevel)
{
if (floorUpList[level] == 1)
{
floorUpList[level] = 0;
elevatorState = STOP;
return;
}
}
}
Sleep(HZ);
} while (true);
}
void Elevator::liftUp()
{
int level;
do {
elevatorHight.nowHight += elevatorHight.moveSpeed;
level = elevatorHight.nowHight / elevatorHight.levelHigh;
int i;
for ( i = level + 1; i < elevatorHight.fullLevel; i++)
{
if ((floorUpList[i] == 1) || (panelButtonList[i] == 1))
{
break;
}
}
if (elevatorHight.nowHight % elevatorHight.levelHigh == 0)
{
if ((floorUpList[level] == 1) || (panelButtonList[level] == 1))
{
floorUpList[level] = 0;
panelButtonList[level] = 0;
elevatorState = STOP;
return;
}
if (i == elevatorHight.fullLevel)
{
if (floorDownList[level] == 1)
{
floorDownList[level] = 0;
elevatorState = STOP;
return;
}
}
}
Sleep(HZ);
} while (true);
}
void Elevator::liftStop()
{
while (true)
{
int level = elevatorHight.nowHight / elevatorHight.levelHigh;
if (doorState != CLOSE)
{
Sleep(HZ*10);
continue;
}
if (liftDirection == LIFT)
{
for (int i = level + 1; i < elevatorHight.fullLevel; i++)
{
if (floorUpList[i] || panelButtonList[i])
{
liftDirection = LIFT;
elevatorState = UP;
return;
}
}
for (int i = elevatorHight.fullLevel; i > level ; i--)
{
if (floorDownList[i])
{
liftDirection = LIFT;
elevatorState = UP;
return;
}
}
floorDownList[level] = 0;
liftDirection = SUSPEND;
}
else if (liftDirection == DROP)
{
for (int i = 0; i < level; i++)
{
if (floorDownList[i] || panelButtonList[i])
{
liftDirection = DROP;
elevatorState = DOWN;
return;
}
}
for (int i = 0; i < level; i++)
{
if (floorUpList[i])
{
liftDirection = DROP;
elevatorState = DOWN;
return;
}
}
liftDirection = SUSPEND;
}
else
{
if (floorDownList[level] || floorUpList[level] || panelButtonList[level])
{
doorState = OPENING;
floorDownList[level] = 0;
floorUpList[level] = 0;
panelButtonList[level] = 0;
continue;
}
for (int i = level + 1; i < elevatorHight.fullLevel; i++)
{
if (floorDownList[i] || floorUpList[i] || panelButtonList[i])
{
liftDirection = LIFT;
}
}
for (int i = level - 1; i >= 0; i--)
{
if (floorDownList[i] || floorUpList[i] || panelButtonList[i])
{
liftDirection = DROP;
}
}
}
Sleep(1);
}
}
DWORD WINAPI Elevator::elevatorThread(void* p)
{
Elevator *elevator = (Elevator*)p;
while (true)
{
switch (elevator->elevatorState)
{
case UP:
elevator->liftUp();
break;
case DOWN:
elevator->liftDown();
break;
case STOP:
elevator->liftStop();
break;
}
Sleep(1);
}
return 0;
}
未完待续、、、
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)