48673

Модель регулятора уровня жидкости

Курсовая

Коммуникация, связь, радиоэлектроника и цифровые приборы

Подводящая и отводящая труба – объекты одного класса TTube. Верхний и нижний датчик – объекты одного класса TSensor. Поэтому вводится понятие модели объект Relity класса TRelity. При этом отпадает необходимость в наличии класса TSignl.

Русский

2013-12-22

99 KB

3 чел.

1. ФОРМУЛИРОВКА ЗАДАЧИ

Модель регулятора уровня жидкости

Выполнить наглядное моделирование процесса регулирования уровня жидкости в емкости. В ёмкость через трубу сверху поступает жидкость, и через трубу снизу жидкость отводится. В отводящей трубе установлена заслонка. В ёмкости установлены два датчика уровня. Первый датчик подаёт сигнал “открыть заслонку”, если он погружён в жидкость. Второй датчик вырабатывает сигнал “закрыть заслонку”, если он не погружён в жидкость. Пользователю предлагается возможность изменять высоту расположения датчика и производительность потока из подводящей трубы. Во время эксперимента в цифровой форме отображается производительность потока жидкости и количество жидкости в ёмкости.

2. СИСТЕМНЫЙ АНАЛИЗ

2.1. Составление словаря системной области.

2.1.1. Перечислим факты, характеризующие системную область:

  1.  В ёмкость поступает жидкость.
  2.  Жидкость поступает через трубу сверху.
  3.  Жидкость отводится через трубу снизу.
  4.  В отводящей трубе установлена заслонка.
  5.  В ёмкости установлены два датчика уровня.
  6.  Первый датчик подаёт сигнал, если он погружен в жидкость.
  7.  Второй датчик подает сигнал, если он не погружён в жидкость.
  8.  Первый датчик подаёт сигнал “открыть заслонку”.
  9.  Второй датчик подаёт сигнал “закрыть заслонку”.
  10.  Пользователь может изменять высоту расположения датчиков и производительность потока из подводящей трубы.
  11.  В цифровой форме отображается производительность потока жидкости и количество жидкости в ёмкости.

2.1.2. Перечислим все объекты (существительные) с указанием фактов, в которых они упоминаются.

  1.  Ёмкость (1, 5, 11).
  2.  Жидкость (1, 2, 3, 6, 7, 11).
  3.  Подводящая труба (2, 10).
  4.  Отводящая труба (3, 4).
  5.  Заслонка (4, 8, 9).
  6.  Верхний датчик (5, 6, 8, 10).
  7.  Нижний датчик (5, 7, 9, 10).
  8.  Сигнал открыть заслонку” (6, 8).
  9.  Сигнал закрыть заслонку” (7, 9).
  10.  Производительность потока из подводящей трубы (10, 11).
  11.  Количество жидкости в ёмкости (11).


2.1.3. Разделим факты, относящиеся к каждому объекту, на три группы: “атрибуты”, ”поведение” и ”сообщения другим объектам”. В результате получим словарь системной области.

  •  Модель. (TReality)
  •  Атрибуты

Регулятор. (Regulator)

  •  Действия

Начать моделирование. (Run)

  •  Регулятор. (TRegulator)
  •  Атрибуты

Ёмкость (Vessel)

Подводящая труба (InTube).

Отводящая труба (OutTube).

Верхний датчик (HiSensor).

Нижний датчик (LoSensor).

  •  Действия

Изменить высоту датчика (ChangeHeight).

Изменить производительность потока (ChangePressure).

  •  Ёмкость. (TVessel)
  •  Атрибуты

Количество жидкости (LiquidAmount).

  •  Действия

Сообщить количество жидкости. (GetLiquidAmount)

Изменить количество жидкости. (ChangeLiquidAmount).

  •  Труба. (TTube)
  •  Атрибуты

Производительность. (Pressure)

Состояние. (State)

  •  Действия

Сообщить текущую производительность потока. (GetPressure)

Изменить производительность потока. (ChangePressure)

Закрыть / открыть заслонку (SetState)

  •  Сообщения другим объектам

Изменить количество жидкости. (MoveLiquid)

  •  Датчик. (TSensor)
  •  Атрибуты

Высота. (Height)

Вырабатываемый сигнал. (Signal)

Тип датчика. (SensorType)

  •  Действия

Сообщить высоту датчика. (GetHeight)

Установить высоту датчика. (SetHeight)

  •  Сообщения другим объектам

Подать сигнал.

  •  Сигнал. (TSignal)
  •  Атрибуты

Содержание. (What)

2.1.4. Примечания к словарю системной области.

  •  Подводящая и отводящая труба – объекты одного класса TTube. Верхний и нижний датчик – объекты одного класса TSensor. Это сделано для простоты, чтобы не усложнять схему наследования классов. Поведение этих объектов полностью определяется их атрибутами, общими для всех объектов, поэтому использовать наследование нецелесообразно.
  •  На моделируемый регулятор уровня жидкости оказывается воздействие со стороны внешнего источника (команды – изменить производительность потока, изменить высоту датчика). Поэтому вводится понятие модели (объект Reality класса TReality). Этот объект генерирует внешние события и воздействует на моделируемый регулятор (Run).

2.2. Техническое задание на проектирование

2.2.1. Функции системы.

  •  Отображение на экране монитора работы регулятора уровня жидкости в сосуде.
  •  Жидкость поступает в ёмкость по трубе сверху, имеется возможность изменить производительность потока этой трубы.
  •  Жидкость отводится из трубы снизу. У этой трубы - два состояния (открыто/закрыто), которые переключаются по сигналам от датчиков, установленных в ёмкости.
  •  В ёмкости установлены два датчика – верхний и нижний. Верхний подаёт сигнал открыть” отводящей трубе, если он погружен в жидкость. Нижний подаёт сигнал “закрыть” отводящей трубе, если он не погружён в жидкость. Имеется возможность регулировать высоту датчиков.
  •  На экране в цифровой форме отображается производительность верхней трубы и количество жидкости в ёмкости.
  •  Управление моделированием осуществляется при помощи команд, подаваемых с клавиатуры: изменить высоту датчика (клавиши , , , ), изменить производительность верхней трубы (клавиши +, - ), завершить работу программы (клавиша “Q”).

2.2.2. Эксплуатационные требования.

  •  Технические средства – ПЭВМ IBM PC;
  •  Операционная система – MS DOS;
  •  Процесс моделирования управляется одним оператором.

2.2.3. Ограничения на процесс разработки.

  •  Срок выполнения проекта – 24 мая 1999 года.

2.2.4. Диаграммы классов и объектов на стадии анализа приведены в Приложении 1.

3. ПРОЕКТИРОВАНИЕ

3.1. Идентификация классов и объектов

 

  •  По отношению к программной системе должны возникать внешние события: сигнал изменения высоты датчика, сигнал изменения производительности потока, сигнал начала моделирования. Кроме того, необходимо предусмотреть дополнительное событие - сигнал об окончании работы программной системы. Поэтому синтезируем класс "событие" (TEvent). При этом отпадает необходимость в наличии класса TSignal.
  •  Реальные объекты существуют в реальном времени, а для моделирования должно быть введено модельное время. Здесь могут быть реализованы различные механизмы. Первый вариант - проектирование процессов реального времени, при котором сигнал об изменении времени поступает извне программной системы, например, от таймера. Другой вариант - имитация времени самой программной системой. В данной курсовой работе реализуем первый вариант. Функцию генерации события наступления моментов времени возложим на объект класса "таймер" (TTimer).
  •  Проектируемая система должна обеспечивать отображение моделируемых объектов в виде графических фигур на экране дисплея. Каждый объект привязывается к определенной точке экрана. Поэтому вводим класс "точка" (TPiont) и класс "фигура" (TFigure), последний обобщает графические свойства всех графических объектов.

3.2. Идентификация содержания классов

На этом шаге последовательно рассмотрим все классы, полученные в процессе выполнения анализа и синтеза.

Класс TPoint. Положение точки определяется координатами X и Y, которые являются атрибутами. Реальные объекты и их графические образы имеют разные линейные размеры и системы координат, поэтому для рассматриваемого класса следовало бы ввести еще один атрибут – масштаб. Для простоты будем считать что размеры всех графических объектов измеряются в единицах экранных координат.

Класс TFigure. Графические объекты в целом характеризуются своим положением на экране, поэтому атрибутом класса TFigure являются координаты левого верхнего угла прямоугольника, в котором располагается фигура (Origin). Графический объект при создании должен сразу располагаться в каком-то месте, поэтому для него требуется соответствующий конструктор. При моделировании изменения состояния фигур требуется убирать их изображения и перерисовывать, поэтому вводятся соответствующие правила Hide и Show. Введём также метод Draw, который будет отвечать за прорисовку объекта, и в зависимости от значения параметра Visible будет либо показывать, либо скрывать объект.

Класс TEvent. Событие характеризуется некоторым значением, по которому одно событие отличается от другого. Для хранения такого значения вводим общедоступный атрибут What.

Класс TTimer. Характеристиками таймера является длительность периода Interval между генерируемыми событиями и текущее значение счетчика CurTime. При создании соответствующего объекта следует установить его в начальное состояние и запомнить длительность периода генерации событий, для чего и вводится конструктор. Кроме того, основным назначением таймера является генерация событий и передача потребителю, что реализуется методом HandleEvent.

Далее рассмотрим классы, которые были "открыты" на стадии системного анализа.

Класс TVessel. Атрибутом данного класса является количество жидкости (LiquidAmount). Для получения / установки значения этого атрибута введём соответственно методы GetLiquidAmount и ChangeLiquidAmount. Переопределим для данного класса метод Draw, который будет рисовать частично заполненную ёмкость, при этом степень заполненности зависит от значения атрибута LiquidAmount.

Класс TTube. Атрибутами данного класса являются: тип трубы (TubeType), производительность потока (Pressure), состояние заслонки (State). Определим метод MoveLiquid, возвращающий значение изменения объёма жидкости в единицу времени (в зависимости от значений атрибутов Pressure и State). Переопределим для класса метод Draw, который будет рисовать трубу, направленную вниз или вверх (в зависимости от атрибута TubeType), частично, полностью или совсем не заполненную водой (в зависимости от атрибутов State и Pressure), с открытой или закрытой заслонкой (атрибут State). Для получения / изменения значения атрибута Pressure определим соответственно методы GetPressure и ChangePressure. Для установки состояния заслонки (атрибут State) введём метод SetState.

Класс TSensor. Определим для данного класса следующие атрибуты – тип (SensorType), высота (Height) и вырабатываемый сигнал (Signal). Определим методы GetHeight и ChangeHeight для доступа к полю Height, метод Show для прорисовки датчика в зависимости от значения атрибутов Height и Signal, и метод GetSignal для получения текущего состояния датчика (наличие/отсутствие сигнала).

Класс TRegulator. Для данного класса определим следующие атрибуты: Vessel – объект типа TVessel; InTube и OutTube – объекты типа TTube; HiSensor и LoSensor – объекты типа TSensor. Внешние события должны восприниматься объектом класса TRegulator, поэтому необходимо ввести соответствующий метод HandleEvent. Кроме того, необходимо предусмотреть метод Update, который изменяет состояние всех составных частей объекта класса TRegulator так, как будто прошел интервал времени еденичной длины. Определим дополнительный атрибут ActiveSensor, содержащий указатель на датчик, высота которого изменяется пользователем в данный момент.

Класс TReality. Объект данного класса содержит в себе в качестве атрибутов объект класса TRegulator и объект класса TTimer.

3.3. Идентификация связей между классами и объектами

  •  Обработка внешних событий ведется методами HandleEvent объектов типа TReality (приём событий от таймера и оператора, передача событий объекту типа TRegulator) и TRegulator (обработка событий).
  •  Метод Update объекта TRegulator изменяет состояние объектов InTube, OutTube, Vessel, UpSensor, DownSensor и вызывает перерисовку всех объектов системы.
  •  Сигнал, вырабатываемый датчиком, реализуется с помощью специального атрибута Signal класса TSensor. Метод Update класса TRegulator постоянно анализирует состояние этого атрибута, и при необходимости изменяет состояние объекта OutTube

3.4. Реализация классов и объектов

Все разработанные классы и выявленные объекты должны быть включены в проект. Уточненные диаграммы классов и объектов показаны в Приложении 1. Для диаграммы объектов составлена диаграмма взаимодействия, иллюстрирующая порядок взаимодействия кометы с другими объектами.

Относительно универсальные классы TPoint и TFigure, могут быть использованы в любой графической программной системе. Они составят модуль Figures. Оставшиеся классы относятся к изучаемой предметной области и будут входить в модуль LLReg (Liquid Level Regulator). Кроме того, для графического изображения простейших фигур необходимо использовать стандартный модуль графики Graphics. Головная программа main в данном случае является единственной и содержит инициализацию, выполнение и уничтожение единственного объекта класса TReality. Вся программная система реализуется одним процессом, поэтому нет необходимости составлять диаграмму процессов.

4. ПРОГРАММИРОВАНИЕ

Программирование выполняется на языке С++, что определено общими требованиями к курсовой работе. Основу для программирования составляют диаграммы и спецификации этапа проектирования. Необходимые детали разъясняются комментариями в тексте программы в Приложении 2.

5. ТЕСТИРОВАНИЕ


П
риложение 1 (рисунки)

Приложение 2 (текст программы)

// events.h - описание класса TEvent и констант событий

#ifndef events_h

#define events_h

// константы событий

enum TEvConstant

{

evNothing,           // событий нет

evTick,              // событие от таймера

evQuit,              // завершение работы программы

evIncreasePressure,  // увеличить давление

evDecreasePressure,  // уменьшить давление

evIncreaseHeight,    // увеличить высоту датчика

evDecreaseHeight,    // уменьшить высоту датчика

evLeftSensor,        // изменить высоту левого датчика

evRightSensor        // изменить высоту правого датчика

};

// Описание класса TEvent

class TEvent

{

public:

 TEvConstant What;   // тип события

};

#endif// figures.h - Интерфейс модуля графических фигур

#ifndef figures_h

#define figures_h

// Описание класса TPoint

class TPoint

{

public:

 int X,Y;         // экранные координаты точки

};

// Описание класса TFigure

class TFigure

{

protected:

 TPoint Origin;  // координаты левого верхнего угла фигуры

public:

 TFigure(int X, int Y);                 // конструктор

 virtual void Draw(int Visible) = 0;    // прорисовка объекта

 virtual void Show();

 virtual void Hide();

 TPoint GetOrigin();                    // методы для доступа к полю Origin

 void SetOrigin(TPoint Point);           

};

#endif

// figures.cpp - Реализация модуля графических фигур

#include "figures.h"

#include <graphics.h>

// Методы класса TFigure

TFigure::TFigure(int X, int Y)

{

TPoint tmp;   

tmp.X = X;

tmp.Y = Y;

Origin = tmp;    // Инициализация объекта Origin параметрами конструктора

};

void TFigure::Show()

{

Draw(1);         // Нарисовать фигуру

};

void TFigure::Hide()

{

Draw(0);         // Спрятать фигуру (закрасить черным)

};

TPoint TFigure::GetOrigin()

{

return Origin;   // возвращает координаты фигуры

};

void TFigure::SetOrigin(TPoint Point)

{

Origin = Point;  // изменение координат фигуры

};

// regparts.h - интерфейс модуля regparts (Классы TVessel, TTube, TSensor)

#ifndef regparts_h

#define regparts_h

#include "figures.h"

enum TTubeTypes {tInTube, tOutTube};             // типы труб

enum TTubeStates {stClosed, stOpen};             // состояния трубы

enum TSensorTypes {tHiSensor, tLoSensor};        // типы датчиков

enum TSensorSignal {sigNone, sigClose, sigOpen}; // типы сигналов датчиков

// Описание класса TVessel (емкость)

class TVessel : public TFigure

{

private:

 float LiquidAmount;    // Количество жидкости

 float Capacity;        // Максимальный объем жидкости

public:

 TVessel(float parCap, int parX, int parY);

 void Draw(int Visible);            // переопределенный метод для прорисовки

 float GetLiquidAmount();           // методы для доступа к полю LiquidAmount

 void ChangeLiquidAmount(float Delta);

};

// Описание класса TTube (труба)

class TTube : public TFigure

{

private:

 TTubeTypes TubeType;   // Тип трубы (входящая/отводящая)

 TTubeStates State;     // Состояние трубы (открыто/закрыто)

 float Pressure;        // Производительность (давление)

public:

 TTube(TTubeTypes parType, float parPressure, int parX, int ParY);

 void Draw(int Visible);               // переопределение метода для прорисовки

 float GetPressure();                  // методы для доступа к полю Pressure

 void ChangePressure(float Delta);

 void SetState(TTubeStates NewState);  // установка состояния трубы

 float MoveLiquid(); // возвращает количество жидкости, перенесенной трубой

                     // в единицу времени (с учетом давления и состояния)                

};

// Описание класса TSensor (датчик)

class TSensor : public TFigure

{

private:

 TSensorTypes SensorType; // тип датчика (верхний/нижний)

 TSensorSignal Signal;    // текущий сигнал датчика

 int Height;              // высота на которой расположен датчик

public:

 TSensor(TSensorTypes parType, int parHeight, int parX, int parY);

 void Draw(int Visible);       // переопределение метода для прорисовки

 int GetHeight();              // методы для доступа к полю Height

 void ChangeHeight(int Delta);

 TSensorSignal GetSignal(int Level); // возвращает сигнал датчика

};

#endif// regparts.cpp - реализация модуля regparts (классы TVessel, TTube, TSensor)

#include <graphics.h>

#include "regparts.h"

// Методы класса TVessel

TVessel::TVessel(float parCap, int parX, int parY) : TFigure(parX, parY)

{

Capacity = parCap;     // инициализация полей

LiquidAmount = 0;

};

void TVessel::Draw(int Visible)

{

int X1 = Origin.X;

int Y1 = Origin.Y;

if (!Visible)                      // реализация закрашивания (Hide)

{

 setcolor(BLACK);

 setfillstyle(SOLID_FILL,BLACK);

 bar(X1,Y1,X1+202,Y1+402);

 return;

};

setcolor(WHITE);                   // прорисовка объекта (Show)

line(X1,Y1,X1+202,Y1);

line(X1+202,Y1,X1+202,Y1+402);

line(X1+202,Y1+402,X1,Y1+402);

line(X1,Y1+11,X1,Y1+391);

setfillstyle(SOLID_FILL,BLACK);

bar(X1+1,Y1+1,X1+201,Y1+401-LiquidAmount);

setfillstyle(SOLID_FILL,BLUE);

bar(X1+1,Y1+401-LiquidAmount,X1+201,Y1+401);

};

float TVessel::GetLiquidAmount() // возвращает текущее количество жидкости

{

return LiquidAmount;

};

void TVessel::ChangeLiquidAmount(float Delta)

{

 // изменение количества жидкости на Delta (с учетом макс. емкости сосуда)

if (Delta == 0) return;

float testLA = LiquidAmount + Delta;

if (testLA > Capacity) LiquidAmount = Capacity;

else if (testLA < 0) LiquidAmount = 0;

     else LiquidAmount = testLA;

setfillstyle(SOLID_FILL,BLACK); // закрашиваем поле для вывода нового

bar(525,120,640,130);           //  количества жидкости

};

// Методы объекта TTube

TTube::TTube(TTubeTypes parType, float parPressure, int parX, int parY)

: TFigure(parX, parY)

{

TubeType = parType;      // Инициализация полей

Pressure = parPressure;

if (TubeType == tInTube) State = stOpen;

else State = stClosed;

};

void TTube::Draw(int Visible)

{

int X1 = Origin.X;

int Y1 = Origin.Y;

if(!Visible)                      // Закрашивание черным цветом (Hide)

{

 setfillstyle(SOLID_FILL,BLACK);

 bar(X1,Y1,X1+100,Y1+10);

 return;

};

setcolor(WHITE);                  // Прорисовка в зависимости от текущего

line(X1,Y1,X1+100,Y1);            //  состояния трубы

line(X1,Y1+10,X1+100,Y1+10);

int col1 = BLUE, col2 = BLUE;

if (State == stClosed)

{

 if (TubeType == tOutTube) col1 = BLACK;

 else col2 = BLACK;

};

if ((Pressure == 0)&&(TubeType == tInTube))

 col1 = BLACK, col2 = BLACK;

setfillstyle(SOLID_FILL,col1);

bar(X1,Y1+1,X1+50,Y1+9);

setfillstyle(SOLID_FILL,col2);

bar(X1+51,Y1+1,X1+100,Y1+9);

if (State == stClosed) line(X1+50,Y1,X1+50,Y1+10);

};

float TTube::GetPressure()   // возвращает текущую производительность трубы

{

return Pressure;

};

void TTube::ChangePressure(float Delta) // изменение давления на Delta

{

float testP = Pressure + Delta;

if (testP < 0) Pressure = 0;

else if (testP > 10) Pressure = 10;

     else Pressure = testP;

setfillstyle(SOLID_FILL,BLACK);        // закрашиваем поле для вывода

bar(525,100,640,110);                  //  нового значения давления

};

void TTube::SetState(TTubeStates NewState)  // Установка состояния трубы

{

State = NewState;

};

float TTube::MoveLiquid()

{

 // Метод возвращает количество жидкости, перенесенной трубой

 //  в единицу времени с учетом типа трубы и состояния заслонки

int sign = (TubeType == tInTube) ? +1 : -1;

if (State == stClosed) sign = 0;

return Pressure * sign;

};

// Методы класса TSensor

TSensor::TSensor(TSensorTypes parType, int parHeight, int parX, int parY) :

TFigure(parX, parY)

{

SensorType = parType;   // Иницицализация полей

Signal = sigNone;

Height = parHeight;

};

void TSensor::Draw(int Visible)

{

  // Реализация прорисовки в зависимости от состояния датчика

int X1 = Origin.X;

int Y1 = Origin.Y - Height;

int col = (Signal == sigNone) ? (LIGHTGREEN):(LIGHTRED);

if (Visible) setcolor(col);

 else setcolor (BLACK);

line(X1-9,Y1,X1+9,Y1);

};

int TSensor::GetHeight()

{

return Height;  // возвращает текущую высоту датчика

};

void TSensor::ChangeHeight(int Delta) // изменение высоты датчика на Delta

{

Hide();

int testH = Height + Delta;

if (testH > 389) testH = 389;

else if (testH < 11) testH = 11;

Height = testH;

Show();

};

TSensorSignal TSensor::GetSignal(int Level)

{

 // Возвращает сигнал в зависимости от уровня жидкости, высоты и типа датчика

Signal = sigNone;

switch (SensorType)

{

 case tLoSensor:

   if (Level < Height) Signal = sigClose; break;

 case tHiSensor:

   if (Level > Height) Signal = sigOpen;  break;

};

return Signal;

};

// reg.h - Заголовок модуля Reg (Описание класса TRegulator)

#ifndef reg_h

#define reg_h

#include "regparts.h"

#include "events.h"

class TRegulator

{

private:

 TVessel *Vessel;          // Поля класса - емкость, входная и выходная трубы,

 TTube *InTube, *OutTube;  // верхний и нижний датчики, текущий датчик

 TSensor *LoSensor, *HiSensor, *ActiveSensor;

public:

 TRegulator();

 ~TRegulator();

 void HandleEvent(TEvent *Event); // Метод обработки событий

 void Update();                   // Обновление всех компонентов регулятора

 void ShowAll();                  // Вывод на экран всех компонентов

 void ShowParams();               // Вывод текущих параметров регулятора

};

#endif

// reg.cpp - Реализация модуля Reg (Класс TRegulator)

#include "reg.h"

#include <graphics.h>

#include <stdio.h>

TRegulator::TRegulator()

{

Vessel = new TVessel(400,100,25);              // Создание всех компонентов

InTube = new TTube(tInTube,9,0,25);

OutTube = new TTube(tOutTube,10,0,417);

LoSensor = new TSensor(tLoSensor,100,90,425);

HiSensor = new TSensor(tHiSensor,300,312,425);

ActiveSensor = LoSensor;  // Делаем текущим нижний датчик

};

TRegulator::~TRegulator()

{

delete HiSensor;   // Удаление из памяти всех компонентов

delete LoSensor;

delete OutTube;

delete InTube;

delete Vessel;

};

void TRegulator::HandleEvent(TEvent *Event)

{

// Определим макрос - конец обработки события в операторе switch

#define END_OF_EVENT Event->What = evNothing; \

                    break

// Обработка событий

switch (Event->What)

{

 case evTick:

   Update(); END_OF_EVENT;

 case evIncreasePressure:

   InTube->ChangePressure(+1);     END_OF_EVENT;

 case evDecreasePressure:

   InTube->ChangePressure(-1);     END_OF_EVENT;

 case evIncreaseHeight:

   if ((HiSensor->GetHeight() - LoSensor->GetHeight()) > 1)

    ActiveSensor->ChangeHeight(+1);

   else if (ActiveSensor == HiSensor)

    ActiveSensor->ChangeHeight(+1);END_OF_EVENT;

 case evDecreaseHeight:

   if ((HiSensor->GetHeight() - LoSensor->GetHeight()) > 1)

    ActiveSensor->ChangeHeight(-1);

   else if (ActiveSensor == LoSensor)

    ActiveSensor->ChangeHeight(-1);END_OF_EVENT;

 case evLeftSensor:

   ActiveSensor = LoSensor;        END_OF_EVENT;

 case evRightSensor:

   ActiveSensor = HiSensor;        END_OF_EVENT;

};

#undef END_OF_EVENT     // отмена макроса END_OF_EVENT

};

// Обновление всех компонентов регулятора (после события evTick)

void TRegulator::Update()

{

float delta = InTube->MoveLiquid() + OutTube->MoveLiquid();

Vessel->ChangeLiquidAmount(delta);               // Изменяем объем жидкости

float curLA = Vessel->GetLiquidAmount();         //  в емкости

TSensorSignal sig1 = LoSensor->GetSignal(curLA); // Опрашиваем датчики

TSensorSignal sig2 = HiSensor->GetSignal(curLA);

TSensorSignal sig = sig1;                        // Находим сигнал

if (sig1 == sigNone) sig = sig2;

switch (sig)                    // Передаем сигнал выходной трубе

{

 case sigOpen  : OutTube->SetState(stOpen);   break;

 case sigClose : OutTube->SetState(stClosed); break;

};

ShowAll();                      // Перерисовка всех объектов

};

void TRegulator::ShowAll()

{

Vessel->Show();        // Перерисовка всех компонентов регулятора

InTube->Show();

OutTube->Show();

HiSensor->Show();

LoSensor->Show();

ShowParams();          // Вывод текущих параметров

};

void TRegulator::ShowParams()

{

setcolor(WHITE);

char buffer[80];       // Буфер для форматирования строки

sprintf(buffer, "     Pressure : %.2f", InTube->GetPressure());

outtextxy(400,100,buffer); // Вывод значения давления

sprintf(buffer, "Liquid amount : %.2f", Vessel->GetLiquidAmount());

outtextxy(400,120,buffer); // Вывод количества жидкости

};

// reality.h - Заголовок модуля элементов модели регулятора

#ifndef reality_h

#define reality_h

#include "reg.h"

#include "events.h"

// константы проектирования

int const cTimerInterval = 1; // период генерации событий времени

// Описание класса TTimer

class TTimer

{

private:

 long CurTime;         // текущее время

 int Interval;         // период генерации события evTick

public:

 TTimer(int anInterval);

 void HandleEvent(TEvent *Event);

};

// Описание класса TReality

class TReality

{

private:

 TRegulator *Regulator; // Поля - указатели на TRegulator и TTimer

 TTimer *Timer;

public:

 TReality();

 ~TReality();

 void Run();            // основной цикл обработки событий программы

};

#endif

// reality.cpp - Реализация модуля элементов модели регулятора

#include "reality.h"

#include <graphics.h>

#include <ctype.h>

#include <conio.h>

#include <bios.h>

// Методы класса TTimer

TTimer::TTimer(int anInterval)

{

Interval = anInterval;        // задаем интервал генерации evTick

long dummy = 0;               // фиктивная переменная для вызова biostime

CurTime = biostime(0,dummy);  // запоминаем текущее время

};

void TTimer::HandleEvent(TEvent* Event)

{

long tmp;

long dummy = 0;

long NextTime = CurTime + Interval; // вычисляем время следующего события evTick

tmp = biostime(0,dummy);            // узнаем текущее время

if((tmp >= NextTime)||(NextTime-tmp > Interval))

{

 CurTime = tmp;        // если время пришло, то устанавливаем новое значение

 Event->What = evTick; // CurTime и генерируем событие evTick

};

};

// Методы класса TReality

TReality::TReality()

{

int gdriver = DETECT;                  // Установка графического режима

int gmode;

initgraph(&gdriver, &gmode,"");

setcolor(GREEN);                       // Вывод подсказки

outtextxy(400,300,"Control keys");

outtextxy(330,320,"<- / ->   : Switch active sensor");

outtextxy(330,340,"Up / Down : Change height");

outtextxy(330,360," + / -    : Increase/Decrease pressure");

outtextxy(330,380,"   Q      : Quit");

Timer = new TTimer(cTimerInterval);    // Создание таймера

Regulator = new TRegulator;            // Создание объекта Регулятор

}

TReality::~TReality()

{

delete Regulator;      // удаление из памяти объекта Регулятор

delete Timer;          // удаление из памяти таймера

closegraph();          // отмена графического режима (переход в текстовый)

};

void TReality::Run()    // Основной цикл обработки событий

{

TEvent Event;                   // Создание пустого события

Event.What = evNothing;

do {

    Timer->HandleEvent(&Event); // Опрос таймера

    if (kbhit())                // Опрос клавиатуры

     {

      char ch = getch();

      switch(toupper(ch))       // Анализ событий от клавиатуры

        {

          case '+' : Event.What = evIncreasePressure;    break;

          case '-' : Event.What = evDecreasePressure;    break;

          case  0  : switch(getch())

                     {

                       case 75: Event.What = evLeftSensor;     break;

                       case 77: Event.What = evRightSensor;    break;

                       case 72: Event.What = evIncreaseHeight; break;

                       case 80: Event.What = evDecreaseHeight; break;

                     };                                  break;

          case 'Q' : Event.What = evQuit;                break;

        };

     };

    Regulator->HandleEvent(&Event);  // Передача события регулятору

   } while(Event.What != evQuit);    // Выход из цикла обработки событий

};

// main.cpp - Головная программа проекта "Регулятор уровня жидкости"

#include "reality.h"

int main()

{

 TReality Reality;     // создание объекта - модели

 Reality.Run();        // запуск цикла обработки событий

 return 0;

};

15


 

А также другие работы, которые могут Вас заинтересовать

54308. Створення блогу на порталі Мета 52.5 KB
  В своїй статті я написав про створення блогу у гуглівській службі Blogger а в цій зупинюся на створенні блогу на українському порталі Мета основна аудиторія якого зосереджена в Україні. На цій сторінці зліва в колонці під словом Авторизація виконуємо авторизацію блогу з логіном та паролем клацаючи нижче на зелений прямокутник Створити свій блог. 1980 Стать жінка Країна проживання Україна Регіон проживання – Миколаївська область Місто переживання Миколаїв Додатковий еmil – можна дати з інших порталів Контрольне питання Відповідь...
54309. РОБОТА З ТОНКОЛИСТОВИМ МЕТАЛОМ 59 KB
  Далі вчитель демонструє виріб який учні будуть виготовляти. Показуючи сокиру вчитель говорить що вона виготовлена з тонколистового металу який називається жерстю. Вчитель розповідає що для виготовлення виробу потрібно намалювати розгортку в зошиті виготовити макет із нелінованого паперу. Вчитель виконує розгортку на дошці а учні – в зошиті.
54310. Кольорова металургія. Урок економічної і соціальної географії України з компютерною презентацією 1011.5 KB
  Які галузі входять до складу металургійного комплексу Яке місце в структурі промисловості посідає чорна металургія Що спільного у виробництві чорних і кольорових металів 3. 1 Кольорова металургія – багатогалузева галузь промисловості яка включає видобуток збагачення руди виробництво різноманітних кольорових металів та їх сплавів. Особливістю кольорових металів є те що вони мають унікальні якості. До кольорових металів належать: Легкі алюміній титан магній; Важкі мідь свинець цинк олово нікель; Рідкісні ...
54311. Розвязування вправ та задач на додавання, віднімання та множення звичайних дробів 166.5 KB
  Сьогодні на уроці ми будемо з вами розвязувати приклади на різні дії зі звичайними дробами. Розв’язавши приклади ми взнаємо що це за метали яка з них користь в яких продуктах вони знаходяться. кальцій Поки ми з разом розв’язуємо перший приклад двоє учнів самостійно два наступних.
54312. Металургійний комплекс України 6.93 MB
  Мета: повторити поняття металургійний комплекс його склад та значення у господарстві України; повторити план ЕГX галузі промисловості; розглянути особливості сировинної бази виробничий процес типи підприємств; познайомити учнів з проблемами та перспективами розвитку чорної металургії; виховувати бережне ставлення до навколишнього середовища. А Що входить до складу металургійного комплексу Б Яке значення має комплекс у господарстві України В Роль та місце чорної металургії у господарстві...
54313. Металургійна промисловість. Чорна і кольорова металургія 63 KB
  Вміти характеризувати галузеву та територіальну структуру металургії показувати на карті основні райони та найбільші центри металургії пояснювати принципи розміщення різних типів підприємств. 3 хв Актуалізація: Слайд 2 8 хв які галузі господарського комплексу є найбільшими споживачами вугілля Який склад і значення металургійного комплексу Що виробляє чорна металургія Кольорова металургія Які особливості сировинної бази чорної та кольорової металургії в Україні Пригадати форми організації...
54314. Forecasting the Future 33.5 KB
  The process of compiling and interpreting this data -- in other words, preparing a forecast -- is comparable to assembling a jigsaw puzzle. The more data available, the easier it is to see what's going on in the atmosphere and to know what the weather will do next.
54315. RECIPROCAL TEACHING 44.5 KB
  Reciprocal teaching is a reading strategy in which students take turns teaching small sections of the text. It is usually done in small groups. All students initially read a section of the text. One student begins by summarizing a section of the text and questioning the others about the meaning of the section. Any difficult parts are identified and discussed and then predictions are made about the next section to be read.
54316. Методичні рекомендації класному керівникові, щодо організації профільного навчання і допрофільної підготовки в 9-х класах 73 KB
  Доцільно проводити шкільні міжшкільні олімпіади дні відкритих дверей видавати інформаційні матеріали які знайомлять учнів із специфікою вимог і особливостями профільного навчання в різних освітніх закладах району. По суті інформаційна робота повинна стати змістовною подорожжю для учнів по освітній території для чого необхідно спланувати відповідний маршрут форми дати конкретні домовленості про час і форми заходів з керівниками освітніх установ. Частина часу ймовірно кілька годин в цілому слід буде передбачити на...