mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
uart experiments
windows build fix log uart write error uart changes uart changes uart changes uart changes uart changes uart works uart changes verbose uart log uart changes uart changes uart logging uart logging uart changes changes uart changes
This commit is contained in:
1
Button.h
1
Button.h
@@ -49,6 +49,7 @@ class TButton
|
||||
Turn( !m_state ); };
|
||||
inline bool Active() {
|
||||
return (pModelOn) || (pModelOff); };
|
||||
inline uint8_t b() { return m_state ? 1 : 0; };
|
||||
void Update();
|
||||
void Init(std::string const &asName, TModel3d *pModel, bool bNewOn = false);
|
||||
void Load(cParser &Parser, TModel3d *pModel1, TModel3d *pModel2 = NULL);
|
||||
|
||||
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake_modules/")
|
||||
project("eu07++ng")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
include_directories("." "Console" "McZapkie")
|
||||
file(GLOB HEADERS "*.h" "Console/*.h" "McZapkie/*.h")
|
||||
|
||||
@@ -66,11 +67,12 @@ set(SOURCES
|
||||
"translation.cpp"
|
||||
"material.cpp"
|
||||
"lua.cpp"
|
||||
"uart.cpp"
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
add_definitions(-DHAVE_ROUND) # to make pymath to not redefine round
|
||||
set(SOURCES ${SOURCES} "windows.cpp" "Console.cpp" "Console/LPT.cpp" "Console/MWD.cpp" "Console/PoKeys55.cpp" "wavread.cpp")
|
||||
set(SOURCES ${SOURCES} "windows.cpp" "Console.cpp" "Console/LPT.cpp" "Console/PoKeys55.cpp" "wavread.cpp")
|
||||
endif()
|
||||
|
||||
if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
|
||||
@@ -130,6 +132,10 @@ find_package(LuaJIT REQUIRED)
|
||||
include_directories(${LUAJIT_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} ${LUAJIT_LIBRARIES})
|
||||
|
||||
find_package(libserialport REQUIRED)
|
||||
include_directories(${libserialport_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} ${libserialport_LIBRARY})
|
||||
|
||||
if (UNIX)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g")
|
||||
endif()
|
||||
|
||||
9
CMake_modules/Findlibserialport.cmake
Normal file
9
CMake_modules/Findlibserialport.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
find_path(libserialport_INCLUDE_DIR libserialport.h)
|
||||
find_library(libserialport_LIBRARY serialport)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(libserialport DEFAULT_MSG libserialport_LIBRARY libserialport_INCLUDE_DIR)
|
||||
if(libserialport_FOUND)
|
||||
set(libserialport_LIBRARIES ${libserialport_LIBRARY})
|
||||
set(libserialport_INCLUDE_DIRS ${libserialport_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
127
Console.cpp
127
Console.cpp
@@ -13,7 +13,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "McZapkie/mctools.h"
|
||||
#include "LPT.h"
|
||||
#include "Logs.h"
|
||||
#include "MWD.h" // maciek001: obsluga portu COM
|
||||
#include "PoKeys55.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -118,7 +117,6 @@ Console::~Console()
|
||||
{
|
||||
delete PoKeys55[0];
|
||||
delete PoKeys55[1];
|
||||
delete MWDComm;
|
||||
};
|
||||
|
||||
void Console::ModeSet(int m, int h)
|
||||
@@ -166,18 +164,6 @@ int Console::On()
|
||||
break;
|
||||
}
|
||||
|
||||
if (Global::bMWDmasterEnable)
|
||||
{
|
||||
WriteLog("Opening ComPort");
|
||||
MWDComm = new TMWDComm();
|
||||
if (!(MWDComm->Open())) // jeżeli nie otwarł portu
|
||||
{
|
||||
WriteLog("ERROR: ComPort is NOT OPEN!");
|
||||
delete MWDComm;
|
||||
MWDComm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -196,8 +182,6 @@ void Console::Off()
|
||||
PoKeys55[1] = NULL;
|
||||
delete LPT;
|
||||
LPT = NULL;
|
||||
delete MWDComm;
|
||||
MWDComm = NULL;
|
||||
};
|
||||
|
||||
void Console::BitsSet(int mask, int entry)
|
||||
@@ -289,56 +273,6 @@ void Console::BitsUpdate(int mask)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (Global::bMWDmasterEnable)
|
||||
{
|
||||
// maciek001: MWDComm lampki i kontrolki
|
||||
// out3: ogrzewanie sk?adu, opory rozruchowe, poslizg, zaluzjewent, -, -, czuwak, shp
|
||||
// out4: stycz.liniowe, pezekaznikr??nicobwpomoc, nadmiarprzetw, roznicowy obw. g?, nadmiarsilniki, wylszybki, zanikpr?duprzyje?dzienaoporach, nadmiarsprezarki
|
||||
// out5: HASLER */
|
||||
if (mask & 0x0001) if (iBits & 1) {
|
||||
MWDComm->WriteDataBuff[4] |= 1 << 7; // SHP HASLER też
|
||||
if (!MWDComm->bSHPstate) {
|
||||
MWDComm->bSHPstate = true;
|
||||
MWDComm->bPrzejazdSHP = true;
|
||||
}
|
||||
else MWDComm->bPrzejazdSHP = false;
|
||||
}
|
||||
else {
|
||||
MWDComm->WriteDataBuff[4] &= ~(1 << 7);
|
||||
MWDComm->bPrzejazdSHP = false;
|
||||
MWDComm->bSHPstate = false;
|
||||
}
|
||||
if (mask & 0x0002) if (iBits & 2) MWDComm->WriteDataBuff[4] |= 1 << 6; // CA
|
||||
else MWDComm->WriteDataBuff[4] &= ~(1 << 6);
|
||||
if (mask & 0x0004) if (iBits & 4) MWDComm->WriteDataBuff[4] |= 1 << 1; // jazda na oporach rozruchowych
|
||||
else MWDComm->WriteDataBuff[4] &= ~(1 << 1);
|
||||
if (mask & 0x0008) if (iBits & 8) MWDComm->WriteDataBuff[5] |= 1 << 5; // wyłącznik szybki
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 5);
|
||||
if (mask & 0x0010) if (iBits & 0x10) MWDComm->WriteDataBuff[5] |= 1 << 4; // nadmiarowy silników trakcyjnych
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 4);
|
||||
if (mask & 0x0020) if (iBits & 0x20) MWDComm->WriteDataBuff[5] |= 1 << 0; // styczniki liniowe
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 0);
|
||||
if (mask & 0x0040) if (iBits & 0x40) MWDComm->WriteDataBuff[4] |= 1 << 2; // poślizg
|
||||
else MWDComm->WriteDataBuff[4] &= ~(1 << 2);
|
||||
if (mask & 0x0080) if (iBits & 0x80) MWDComm->WriteDataBuff[5] |= 1 << 2; // (nadmiarowy) przetwornicy? ++
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 2);
|
||||
if (mask & 0x0100) if (iBits & 0x100) MWDComm->WriteDataBuff[5] |= 1 << 7; // nadmiarowy sprężarki
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 7);
|
||||
if (mask & 0x0200) if (iBits & 0x200) MWDComm->WriteDataBuff[2] |= 1 << 1; // wentylatory i opory
|
||||
else MWDComm->WriteDataBuff[2] &= ~(1 << 1);
|
||||
if (mask & 0x0400) if (iBits & 0x400) MWDComm->WriteDataBuff[2] |= 1 << 2; // wysoki rozruch
|
||||
else MWDComm->WriteDataBuff[2] &= ~(1 << 2);
|
||||
if (mask & 0x0800) if (iBits & 0x800) MWDComm->WriteDataBuff[4] |= 1 << 0; // ogrzewanie pociągu
|
||||
else MWDComm->WriteDataBuff[4] &= ~(1 << 0);
|
||||
if (mask & 0x1000) if (iBits & 0x1000) MWDComm->bHamowanie = true; // hasler: ciśnienie w hamulcach HASLER rysik 2
|
||||
else MWDComm->bHamowanie = false;
|
||||
if (mask & 0x2000) if (iBits & 0x2000) MWDComm->WriteDataBuff[6] |= 1 << 4; // hasler: prąd "na" silnikach - HASLER rysik 3
|
||||
else MWDComm->WriteDataBuff[6] &= ~(1 << 4);
|
||||
if (mask & 0x4000) if (iBits & 0x4000) MWDComm->WriteDataBuff[6] |= 1 << 7; // brzęczyk SHP/CA
|
||||
else MWDComm->WriteDataBuff[6] &= ~(1 << 7);
|
||||
//if(mask & 0x8000) if(iBits & 0x8000) MWDComm->WriteDataBuff[1] |= 1<<7; (puste)
|
||||
//else MWDComm->WriteDataBuff[0] &= ~(1<<7);
|
||||
}
|
||||
};
|
||||
|
||||
void Console::ValueSet(int x, double y)
|
||||
@@ -371,57 +305,6 @@ void Console::ValueSet(int x, double y)
|
||||
WriteLog(" calibrated=" + std::to_string(temp));
|
||||
PoKeys55[0]->PWM(x, temp);
|
||||
}
|
||||
if (Global::bMWDmasterEnable)
|
||||
{
|
||||
unsigned int iliczba;
|
||||
switch (x)
|
||||
{
|
||||
case 0: iliczba = (unsigned int)floor((y / (Global::fMWDzg[0] * 10) * Global::fMWDzg[1]) + 0.5); // zbiornik główny
|
||||
MWDComm->WriteDataBuff[12] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[11] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main tank press " + to_string(MWDComm->WriteDataBuff[12]) + " " + to_string(MWDComm->WriteDataBuff[11]));
|
||||
break;
|
||||
case 1: iliczba = (unsigned int)floor((y / (Global::fMWDpg[0] * 10) * Global::fMWDpg[1]) + 0.5); // przewód główny
|
||||
MWDComm->WriteDataBuff[10] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[9] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main pipe press " + to_string(MWDComm->WriteDataBuff[10]) + " " + to_string(MWDComm->WriteDataBuff[9]));
|
||||
break;
|
||||
case 2: iliczba = (unsigned int)floor((y / (Global::fMWDph[0] * 10) * Global::fMWDph[1]) + 0.5); // cylinder hamulcowy
|
||||
MWDComm->WriteDataBuff[8] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[7] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Break press " + to_string(MWDComm->WriteDataBuff[8]) + " " + to_string(MWDComm->WriteDataBuff[7]));
|
||||
break;
|
||||
case 3: iliczba = (unsigned int)floor((y / Global::fMWDvolt[0] * Global::fMWDvolt[1]) + 0.5); // woltomierz WN
|
||||
MWDComm->WriteDataBuff[14] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[13] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Hi Volt meter " + to_string(MWDComm->WriteDataBuff[14]) + " " + to_string(MWDComm->WriteDataBuff[13]));
|
||||
break;
|
||||
case 4: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 1
|
||||
MWDComm->WriteDataBuff[16] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[15] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter1 " + to_string(MWDComm->WriteDataBuff[16]) + " " + to_string(MWDComm->WriteDataBuff[15]));
|
||||
break;
|
||||
case 5: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 2
|
||||
MWDComm->WriteDataBuff[18] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[17] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter2 " + to_string(MWDComm->WriteDataBuff[18]) + " " + to_string(MWDComm->WriteDataBuff[17]));
|
||||
break;
|
||||
case 6: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 3
|
||||
MWDComm->WriteDataBuff[20] = (unsigned int)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[19] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter3 " + to_string(MWDComm->WriteDataBuff[20]) + " " + to_string(MWDComm->WriteDataBuff[19]));
|
||||
break;
|
||||
case 7: if (Global::iPause) MWDComm->WriteDataBuff[0] = 0; //skoro pauza to hasler stoi i nie nabija kilometrów CHYBA NIE DZIAŁA!
|
||||
else MWDComm->WriteDataBuff[0] = (unsigned char)floor(y); // prędkość dla np haslera
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Speed: " + to_string(MWDComm->WriteDataBuff[0]));
|
||||
break;
|
||||
case 8: iliczba = (unsigned int)floor((y / Global::fMWDlowVolt[0] * Global::fMWDlowVolt[1]) + 0.5); // volt NN
|
||||
MWDComm->WriteDataBuff[22] = (unsigned int)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[21] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Low Volt meter " + to_string(MWDComm->WriteDataBuff[22]) + " " + to_string(MWDComm->WriteDataBuff[21]));
|
||||
break; // przygotowane do wdrożenia, jeszcze nie wywoływane
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Console::Update()
|
||||
@@ -439,11 +322,6 @@ void Console::Update()
|
||||
Global::iPause |= 8; // tak???
|
||||
PoKeys55[0]->Connect(); // próba ponownego podłączenia
|
||||
}
|
||||
if (Global::bMWDmasterEnable)
|
||||
{
|
||||
if (MWDComm->GetMWDState()) MWDComm->Run();
|
||||
else MWDComm->Close();
|
||||
}
|
||||
};
|
||||
|
||||
float Console::AnalogGet(int x)
|
||||
@@ -468,11 +346,6 @@ float Console::AnalogCalibrateGet(int x)
|
||||
if (x == 1) return b/10;
|
||||
else return b;
|
||||
}
|
||||
if (Global::bMWDmasterEnable && Global::bMWDBreakEnable)
|
||||
{
|
||||
float b = (float)MWDComm->uiAnalog[x];
|
||||
return (b - Global::fMWDAnalogInCalib[x][0]) / (Global::fMWDAnalogInCalib[x][1] - Global::fMWDAnalogInCalib[x][0]);
|
||||
}
|
||||
return -1.0; // odcięcie
|
||||
};
|
||||
|
||||
|
||||
763
Console/MWD.cpp
763
Console/MWD.cpp
@@ -1,763 +0,0 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/*
|
||||
Program obsługi portu COM i innych na potrzeby sterownika MWDevice
|
||||
(oraz innych wykorzystujących komunikację przez port COM)
|
||||
dla Symulatora Pojazdów Szynowych MaSzyna
|
||||
author: Maciej Witek 2016
|
||||
Autor nie ponosi odpowiedzialności za niewłaciwe używanie lub działanie programu!
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "MWD.h"
|
||||
#include "Globals.h"
|
||||
#include "Logs.h"
|
||||
#include "World.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HANDLE hComm;
|
||||
|
||||
TMWDComm::TMWDComm() // konstruktor
|
||||
{
|
||||
MWDTime = 0;
|
||||
bSHPstate = false;
|
||||
bPrzejazdSHP = false;
|
||||
bKabina1 = true; // pasuje wyciągnąć dane na temat kabiny
|
||||
bKabina2 = false; // i ustawiać te dwa parametry!
|
||||
bHamowanie = false;
|
||||
bCzuwak = false;
|
||||
|
||||
bRysik1H = false;
|
||||
bRysik1L = false;
|
||||
bRysik2H = false;
|
||||
bRysik2L = false;
|
||||
|
||||
bocznik = 0;
|
||||
nastawnik = 0;
|
||||
kierunek = 0;
|
||||
bnkMask = 0;
|
||||
|
||||
int i = 6;
|
||||
|
||||
while (i)
|
||||
{
|
||||
i--;
|
||||
lastStateData[i] = 0;
|
||||
maskData[i] = 0;
|
||||
maskSwitch[i] = 0;
|
||||
bitSwitch[i] = 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i<BYTETOWRITE)
|
||||
{
|
||||
if (i<BYTETOREAD)ReadDataBuff[i] = 0;
|
||||
WriteDataBuff[i] = 0;
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while (i<6)
|
||||
{
|
||||
lastStateData[i] = 0;
|
||||
maskSwitch[i] = 0;
|
||||
bitSwitch[i] = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
TMWDComm::~TMWDComm() // destruktor
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool TMWDComm::Open() // otwieranie portu COM
|
||||
{
|
||||
LPCSTR portId = Global::sMWDPortId.c_str();
|
||||
hComm = CreateFile(portId, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hComm == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
WriteLog("PortCOM ERROR: serial port does not exist"); // serial port does not exist.
|
||||
// Inform user.
|
||||
}
|
||||
WriteLog("PortCOM ERROR! not open!");
|
||||
// some other error occurred. Inform user.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DCB CommDCB;
|
||||
CommDCB.DCBlength = sizeof(DCB);
|
||||
GetCommState(hComm, &CommDCB);
|
||||
|
||||
CommDCB.BaudRate = Global::iMWDBaudrate;
|
||||
CommDCB.fBinary = TRUE;
|
||||
CommDCB.fParity = FALSE;
|
||||
CommDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
|
||||
CommDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
|
||||
CommDCB.fDtrControl = FALSE; // DTR flow control type
|
||||
|
||||
CommDCB.fDsrSensitivity = FALSE; // DSR sensitivity
|
||||
CommDCB.fTXContinueOnXoff = FALSE; // XOFF continues Tx
|
||||
CommDCB.fOutX = FALSE; // No XON/XOFF out flow control
|
||||
CommDCB.fInX = FALSE; // No XON/XOFF in flow control
|
||||
CommDCB.fErrorChar = FALSE; // Disable error replacement
|
||||
CommDCB.fNull = FALSE; // Disable null stripping
|
||||
CommDCB.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
|
||||
CommDCB.fAbortOnError = FALSE;
|
||||
|
||||
CommDCB.ByteSize = 8;
|
||||
CommDCB.Parity = NOPARITY;
|
||||
CommDCB.StopBits = ONESTOPBIT;
|
||||
|
||||
// konfiguracja portu
|
||||
if (!SetCommState(hComm, &CommDCB))
|
||||
{
|
||||
// dwError = GetLastError ();
|
||||
WriteLog("Unable to configure the serial port!");
|
||||
return FALSE;
|
||||
}
|
||||
WriteLog("PortCOM OPEN and CONFIG!");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TMWDComm::Close() // zamykanie portu COM
|
||||
{
|
||||
Global::bMWDmasterEnable = false; // główne włączenie portu!
|
||||
Global::bMWDInputEnable = false; // włącz wejścia
|
||||
Global::bMWDBreakEnable = false; // włącz wejścia analogowe
|
||||
|
||||
WriteLog("COM Port is closing...");
|
||||
int i = 0;
|
||||
while (i < BYTETOWRITE) // zerowanie danych...
|
||||
{
|
||||
WriteDataBuff[i] = 0;
|
||||
i++;
|
||||
}
|
||||
Sleep(100);
|
||||
SendData(); // wysyłanie do pulpitu: zatrzymanie haslera i zgaszenie lampek
|
||||
Sleep(700);
|
||||
CloseHandle(hComm);
|
||||
WriteLog("COM is close!");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TMWDComm::GetMWDState() // sprawdzanie otwarcia portu COM
|
||||
{
|
||||
if (hComm > 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TMWDComm::ReadData() // odbieranie danych + odczyta danych analogowych i zapis do zmiennych
|
||||
{
|
||||
DWORD bytes_read;
|
||||
ReadFile(hComm, &ReadDataBuff[0], BYTETOREAD, &bytes_read, NULL);
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog("Data receive. Checking data...");
|
||||
if (Global::bMWDBreakEnable)
|
||||
{
|
||||
uiAnalog[0] = (ReadDataBuff[9] << 8) + ReadDataBuff[8];
|
||||
uiAnalog[1] = (ReadDataBuff[11] << 8) + ReadDataBuff[10];
|
||||
uiAnalog[2] = (ReadDataBuff[13] << 8) + ReadDataBuff[12];
|
||||
uiAnalog[3] = (ReadDataBuff[15] << 8) + ReadDataBuff[14];
|
||||
if (Global::bMWDdebugEnable && (Global::iMWDDebugMode & 1))
|
||||
{
|
||||
WriteLog("Main Break = " + to_string(uiAnalog[0]));
|
||||
WriteLog("Locomotiv Break = " + to_string(uiAnalog[1]));
|
||||
}
|
||||
if (Global::bMWDdebugEnable && (Global::iMWDDebugMode & 2))
|
||||
{
|
||||
WriteLog("Analog input 1 = " + to_string(uiAnalog[2]));
|
||||
WriteLog("Analog imput 2 = " + to_string(uiAnalog[3]));
|
||||
}
|
||||
}
|
||||
if (Global::bMWDInputEnable) CheckData();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TMWDComm::SendData() // wysyłanie danych
|
||||
{
|
||||
DWORD bytes_write;
|
||||
|
||||
WriteFile(hComm, &WriteDataBuff[0], BYTETOWRITE, &bytes_write, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TMWDComm::Run() // wywoływanie obsługi MWD + generacja większego opóźnienia
|
||||
{
|
||||
if (GetMWDState())
|
||||
{
|
||||
MWDTime++;
|
||||
if (!(MWDTime % Global::iMWDdivider))
|
||||
{
|
||||
MWDTime = 0;
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog("Sending data...");
|
||||
SendData();
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog(" complet!\nReceiving data...");
|
||||
ReadData();
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog(" complet!");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLog("Port COM: connection ERROR!");
|
||||
Close();
|
||||
// może spróbować się połączyć znowu?
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterowanie maszyną
|
||||
{
|
||||
int i = 0;
|
||||
while (i < 6)
|
||||
{
|
||||
maskData[i] = ReadDataBuff[i] ^ lastStateData[i];
|
||||
lastStateData[i] = ReadDataBuff[i];
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
Rozpiska portów!
|
||||
Port0: 0 NC odblok. przek. sprężarki i wentyl. oporów
|
||||
1 M wyłącznik wył. szybkiego
|
||||
2 Shift+M impuls załączający wył. szybki
|
||||
3 N odblok. przekaźników nadmiarowych
|
||||
i różnicowego obwodu głównegoMMm
|
||||
4 NC rezerwa
|
||||
5 Ctrl+N odblok. przek. nadmiarowych
|
||||
przetwornicy, ogrzewania pociągu i różnicowych obw. pomocniczych
|
||||
6 L wył. styczników liniowych
|
||||
7 SPACE kasowanie czuwaka
|
||||
|
||||
Port1: 0 NC
|
||||
1 (Shift) X przetwornica
|
||||
2 (Shift) C sprężarka
|
||||
3 S piasecznice
|
||||
4 (Shift) H ogrzewanie składu
|
||||
5 przel. hamowania Shift+B
|
||||
pspbpwy Ctrl+B pospieszny B towarowy
|
||||
6 przel. hamowania
|
||||
7 (Shift) F rozruch w/n
|
||||
|
||||
Port2: 0 (Shift) P pantograf przedni
|
||||
1 (Shift) O pantograf tylni
|
||||
2 ENTER przyhamowanie przy poślizgu
|
||||
3 () przyciemnienie świateł
|
||||
4 () przyciemnienie świateł
|
||||
5 NUM6 odluźniacz
|
||||
6 a syrena lok W
|
||||
7 A syrena lok N
|
||||
|
||||
Port3: 0 Shift+J bateria
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
*/
|
||||
|
||||
/* po przełączeniu bistabilnego najpierw wciskamy klawisz i przy następnym
|
||||
wejściu w pętlę MWD puszczamy bo inaczej nie działa
|
||||
*/
|
||||
|
||||
// wciskanie przycisków klawiatury
|
||||
/*PORT0*/
|
||||
if (maskData[0] & 0x02) if (lastStateData[0] & 0x02)
|
||||
KeyBoard('M', 1); // wyłączenie wyłącznika szybkiego
|
||||
else KeyBoard('M', 0); // monostabilny
|
||||
if (maskData[0] & 0x04) if (lastStateData[0] & 0x04) // impuls załączający wyłącznik szybki
|
||||
{
|
||||
KeyBoard(0x10, 1); // monostabilny
|
||||
KeyBoard('M', 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBoard('M', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
if (maskData[0] & 0x08) if (lastStateData[0] & 0x08)
|
||||
KeyBoard('N', 1); // odblok nadmiarowego silników trakcyjnych
|
||||
else KeyBoard('N', 0); // monostabilny
|
||||
if (maskData[0] & 0x20) if (lastStateData[0] & 0x20)
|
||||
{ // odblok nadmiarowego przetwornicy, ogrzewania poc.
|
||||
KeyBoard(0x11, 1); // różnicowego obwodów pomocniczych
|
||||
KeyBoard('N', 1); // monostabilny
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBoard('N', 0);
|
||||
KeyBoard(0x11, 0);
|
||||
}
|
||||
if (maskData[0] & 0x40) if (lastStateData[0] & 0x40) KeyBoard('L', 1); // wył. styczników liniowych
|
||||
else KeyBoard('L', 0); // monostabilny
|
||||
if (maskData[0] & 0x80) if (lastStateData[0] & 0x80) KeyBoard(0x20, 1); // kasowanie czuwaka/SHP
|
||||
else KeyBoard(0x20, 0); // kasowanie czuwaka/SHP
|
||||
|
||||
/*PORT1*/
|
||||
|
||||
// puszczanie przycisku bistabilnego klawiatury
|
||||
if (maskSwitch[1] & 0x02)
|
||||
{
|
||||
if (bitSwitch[1] & 0x02)
|
||||
{
|
||||
KeyBoard('X', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('X', 0);
|
||||
maskSwitch[1] &= ~0x02;
|
||||
}
|
||||
if (maskSwitch[1] & 0x04) {
|
||||
if (bitSwitch[1] & 0x04) {
|
||||
KeyBoard('C', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('C', 0);
|
||||
maskSwitch[1] &= ~0x04;
|
||||
}
|
||||
if (maskSwitch[1] & 0x10) {
|
||||
if (bitSwitch[1] & 0x10) {
|
||||
KeyBoard('H', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('H', 0);
|
||||
maskSwitch[1] &= ~0x10;
|
||||
}
|
||||
if (maskSwitch[1] & 0x20 || maskSwitch[1] & 0x40) {
|
||||
if (maskSwitch[1] & 0x20) KeyBoard(0x10, 0);
|
||||
if (maskSwitch[1] & 0x40) KeyBoard(0x11, 0);
|
||||
KeyBoard('B', 0);
|
||||
maskSwitch[1] &= ~0x60;
|
||||
}
|
||||
if (maskSwitch[1] & 0x80) {
|
||||
if (bitSwitch[1] & 0x80) {
|
||||
KeyBoard('F', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('F', 0);
|
||||
maskSwitch[1] &= ~0x80;
|
||||
}
|
||||
|
||||
// przetwornica
|
||||
if (maskData[1] & 0x02) if (lastStateData[1] & 0x02)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('X', 1);
|
||||
maskSwitch[1] |= 0x02;
|
||||
bitSwitch[1] |= 0x02;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[1] |= 0x02;
|
||||
bitSwitch[1] &= ~0x02;
|
||||
KeyBoard('X', 1);
|
||||
}
|
||||
// sprężarka
|
||||
if (maskData[1] & 0x04) if (lastStateData[1] & 0x04)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('C', 1);
|
||||
maskSwitch[1] |= 0x04;
|
||||
bitSwitch[1] |= 0x04;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[1] |= 0x04;
|
||||
bitSwitch[1] &= ~0x04;
|
||||
KeyBoard('C', 1);
|
||||
}
|
||||
// piasecznica
|
||||
if (maskData[1] & 0x08) if (lastStateData[1] & 0x08)
|
||||
KeyBoard('S', 1);
|
||||
else
|
||||
KeyBoard('S', 0); // monostabilny
|
||||
// ogrzewanie składu
|
||||
if (maskData[1] & 0x10) if (lastStateData[1] & 0x10)
|
||||
{
|
||||
KeyBoard(0x11, 1); // bistabilny
|
||||
KeyBoard('H', 1);
|
||||
maskSwitch[1] |= 0x10;
|
||||
bitSwitch[1] |= 0x10;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[1] |= 0x10;
|
||||
bitSwitch[1] &= ~0x10;
|
||||
KeyBoard('H', 1);
|
||||
}
|
||||
// przełącznik hamowania
|
||||
if (maskData[1] & 0x20 || maskData[1] & 0x40)
|
||||
{
|
||||
if (lastStateData[1] & 0x20)
|
||||
{ // Shift+B
|
||||
KeyBoard(0x10, 1);
|
||||
maskSwitch[1] |= 0x20;
|
||||
}
|
||||
else if (lastStateData[1] & 0x40)
|
||||
{ // Ctrl+B
|
||||
KeyBoard(0x11, 1);
|
||||
maskSwitch[1] |= 0x40;
|
||||
}
|
||||
KeyBoard('B', 1);
|
||||
}
|
||||
// rozruch wysoki/niski
|
||||
if (maskData[1] & 0x80) if (lastStateData[1] & 0x80)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('F', 1);
|
||||
maskSwitch[1] |= 0x80;
|
||||
bitSwitch[1] |= 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[1] |= 0x80;
|
||||
bitSwitch[1] &= ~0x80;
|
||||
KeyBoard('F', 1);
|
||||
}
|
||||
|
||||
|
||||
//PORT2
|
||||
if (maskSwitch[2] & 0x01)
|
||||
{
|
||||
if (bitSwitch[2] & 0x01)
|
||||
{
|
||||
KeyBoard('P', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('P', 0);
|
||||
maskSwitch[2] &= ~0x01;
|
||||
}
|
||||
if (maskSwitch[2] & 0x02)
|
||||
{
|
||||
if (bitSwitch[2] & 0x02)
|
||||
{
|
||||
KeyBoard('O', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('O', 0);
|
||||
maskSwitch[2] &= ~0x02;
|
||||
}
|
||||
|
||||
// pantograf przedni
|
||||
if (maskData[2] & 0x01) if (lastStateData[2] & 0x01)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('P', 1);
|
||||
maskSwitch[2] |= 0x01;
|
||||
bitSwitch[2] |= 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[2] |= 0x01;
|
||||
bitSwitch[2] &= ~0x01;
|
||||
KeyBoard('P', 1);
|
||||
}
|
||||
// pantograf tylni
|
||||
if (maskData[2] & 0x02) if (lastStateData[2] & 0x02)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('O', 1);
|
||||
maskSwitch[2] |= 0x02;
|
||||
bitSwitch[2] |= 0x02;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[2] |= 0x02;
|
||||
bitSwitch[2] &= ~0x02;
|
||||
KeyBoard('O', 1);
|
||||
}
|
||||
// przyhamowanie przy poślizgu
|
||||
if (maskData[2] & 0x04) if (lastStateData[2] & 0x04) {
|
||||
KeyBoard(0x10, 1); // monostabilny
|
||||
KeyBoard(0x0D, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBoard(0x0D, 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
/*if(maskData[2] & 0x08) if (lastStateData[2] & 0x08){ // przyciemnienie świateł
|
||||
KeyBoard(' ',0); // bistabilny
|
||||
KeyBoard(0x10,1);
|
||||
KeyBoard(' ',1);
|
||||
}else{
|
||||
KeyBoard(' ',0);
|
||||
KeyBoard(0x10,0);
|
||||
KeyBoard(' ',1);
|
||||
}
|
||||
if(maskData[2] & 0x10) if (lastStateData[2] & 0x10) { // przyciemnienie świateł
|
||||
KeyBoard(' ',0); // bistabilny
|
||||
KeyBoard(0x11,1);
|
||||
KeyBoard(' ',1);
|
||||
}else{
|
||||
KeyBoard(' ',0);
|
||||
KeyBoard(0x11,0);
|
||||
KeyBoard(' ',1);
|
||||
}*/
|
||||
// odluźniacz
|
||||
if (maskData[2] & 0x20) if (lastStateData[2] & 0x20)
|
||||
KeyBoard(0x66, 1);
|
||||
else
|
||||
KeyBoard(0x66, 0); // monostabilny
|
||||
// syrena wysoka
|
||||
if (maskData[2] & 0x40) if (lastStateData[2] & 0x40)
|
||||
{
|
||||
KeyBoard(0x10, 1); // monostabilny
|
||||
KeyBoard('A', 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBoard('A', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
if (maskData[2] & 0x80) if (lastStateData[2] & 0x80)
|
||||
KeyBoard('A', 1); // syrena niska
|
||||
else
|
||||
KeyBoard('A', 0); // monostabilny
|
||||
|
||||
|
||||
//PORT3
|
||||
|
||||
if (maskSwitch[3] & 0x01)
|
||||
{
|
||||
if (bitSwitch[3] & 0x01)
|
||||
{
|
||||
KeyBoard('J', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('J', 0);
|
||||
maskSwitch[3] &= ~0x01;
|
||||
}
|
||||
if (maskSwitch[3] & 0x02)
|
||||
{
|
||||
if (bitSwitch[3] & 0x02)
|
||||
{
|
||||
KeyBoard('Y', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('Y', 0);
|
||||
maskSwitch[3] &= ~0x02;
|
||||
}
|
||||
if (maskSwitch[3] & 0x04)
|
||||
{
|
||||
if (bitSwitch[3] & 0x04)
|
||||
{
|
||||
KeyBoard('U', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('U', 0);
|
||||
maskSwitch[3] &= ~0x04;
|
||||
}
|
||||
if (maskSwitch[3] & 0x08)
|
||||
{
|
||||
if (bitSwitch[3] & 0x08)
|
||||
{
|
||||
KeyBoard('I', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('I', 0);
|
||||
maskSwitch[3] &= ~0x08;
|
||||
}
|
||||
|
||||
|
||||
// bateria
|
||||
if (maskData[3] & 0x01) if (lastStateData[3] & 0x01)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('J', 1);
|
||||
maskSwitch[3] |= 0x01;
|
||||
bitSwitch[3] |= 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[3] |= 0x01;
|
||||
bitSwitch[3] &= ~0x01;
|
||||
KeyBoard('J', 1);
|
||||
}
|
||||
//Światło lewe
|
||||
if (maskData[3] & 0x02) if (lastStateData[3] & 0x02)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('Y', 1);
|
||||
maskSwitch[3] |= 0x02;
|
||||
bitSwitch[3] |= 0x02;
|
||||
}else
|
||||
{
|
||||
maskSwitch[3] |= 0x02;
|
||||
bitSwitch[3] &= ~0x02;
|
||||
KeyBoard('Y', 1);
|
||||
}
|
||||
//światło górne
|
||||
if (maskData[3] & 0x04) if (lastStateData[3] & 0x04)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('U', 1);
|
||||
maskSwitch[3] |= 0x04;
|
||||
bitSwitch[3] |= 0x04;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[3] |= 0x04;
|
||||
bitSwitch[3] &= ~0x04;
|
||||
KeyBoard('U', 1);
|
||||
}
|
||||
//światło prawe
|
||||
if (maskData[3] & 0x08) if (lastStateData[3] & 0x08)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('I', 1);
|
||||
maskSwitch[3] |= 0x08;
|
||||
bitSwitch[3] |= 0x08;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[3] |= 0x08;
|
||||
bitSwitch[3] &= ~0x08;
|
||||
KeyBoard('I', 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* NASTAWNIK, BOCZNIK i KIERUNEK */
|
||||
|
||||
if (bnkMask & 1)
|
||||
{ // puszczanie klawiszy
|
||||
KeyBoard(0x6B, 0);
|
||||
bnkMask &= ~1;
|
||||
}
|
||||
if (bnkMask & 2)
|
||||
{
|
||||
KeyBoard(0x6D, 0);
|
||||
bnkMask &= ~2;
|
||||
}
|
||||
if (bnkMask & 4)
|
||||
{
|
||||
KeyBoard(0x6F, 0);
|
||||
bnkMask &= ~4;
|
||||
}
|
||||
if (bnkMask & 8)
|
||||
{
|
||||
KeyBoard(0x6A, 0);
|
||||
bnkMask &= ~8;
|
||||
}
|
||||
|
||||
if (nastawnik < ReadDataBuff[6])
|
||||
{
|
||||
bnkMask |= 1;
|
||||
nastawnik++;
|
||||
KeyBoard(0x6B, 1); // wciśnij + i dodaj 1 do nastawnika
|
||||
}
|
||||
if (nastawnik > ReadDataBuff[6])
|
||||
{
|
||||
bnkMask |= 2;
|
||||
nastawnik--;
|
||||
KeyBoard(0x6D, 1); // wciśnij - i odejmij 1 do nastawnika
|
||||
}
|
||||
if (bocznik < ReadDataBuff[7])
|
||||
{
|
||||
bnkMask |= 4;
|
||||
bocznik++;
|
||||
KeyBoard(0x6F, 1); // wciśnij / i dodaj 1 do bocznika
|
||||
}
|
||||
if (bocznik > ReadDataBuff[7])
|
||||
{
|
||||
bnkMask |= 8;
|
||||
bocznik--;
|
||||
KeyBoard(0x6A, 1); // wciśnij * i odejmij 1 do bocznika
|
||||
}
|
||||
|
||||
/* Obsługa HASLERA */
|
||||
if (ReadDataBuff[0] & 0x80)
|
||||
bCzuwak = true;
|
||||
|
||||
if (bKabina1)
|
||||
{ // logika rysika 1
|
||||
bRysik1H = true;
|
||||
bRysik1L = false;
|
||||
if (bPrzejazdSHP)
|
||||
bRysik1H = false;
|
||||
}
|
||||
else if (bKabina2)
|
||||
{
|
||||
bRysik1L = true;
|
||||
bRysik1H = false;
|
||||
if (bPrzejazdSHP)
|
||||
bRysik1L = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bRysik1H = false;
|
||||
bRysik1L = false;
|
||||
}
|
||||
|
||||
if (bHamowanie)
|
||||
{ // logika rysika 2
|
||||
bRysik2H = false;
|
||||
bRysik2L = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bCzuwak)
|
||||
bRysik2H = true;
|
||||
else
|
||||
bRysik2H = false;
|
||||
bRysik2L = false;
|
||||
}
|
||||
bCzuwak = false;
|
||||
if (bRysik1H)
|
||||
WriteDataBuff[6] |= 1 << 0;
|
||||
else
|
||||
WriteDataBuff[6] &= ~(1 << 0);
|
||||
if (bRysik1L)
|
||||
WriteDataBuff[6] |= 1 << 1;
|
||||
else
|
||||
WriteDataBuff[6] &= ~(1 << 1);
|
||||
if (bRysik2H)
|
||||
WriteDataBuff[6] |= 1 << 2;
|
||||
else
|
||||
WriteDataBuff[6] &= ~(1 << 2);
|
||||
if (bRysik2L)
|
||||
WriteDataBuff[6] |= 1 << 3;
|
||||
else
|
||||
WriteDataBuff[6] &= ~(1 << 3);
|
||||
}
|
||||
|
||||
void TMWDComm::KeyBoard(int key, bool s) // emulacja klawiatury
|
||||
{
|
||||
INPUT ip;
|
||||
// Set up a generic keyboard event.
|
||||
ip.type = INPUT_KEYBOARD;
|
||||
ip.ki.wScan = 0; // hardware scan code for key
|
||||
ip.ki.time = 0;
|
||||
ip.ki.dwExtraInfo = 0;
|
||||
|
||||
ip.ki.wVk = key; // virtual-key code for the "a" key
|
||||
|
||||
if (s)
|
||||
{ // Press the "A" key
|
||||
ip.ki.dwFlags = 0; // 0 for key press
|
||||
SendInput(1, &ip, sizeof(INPUT));
|
||||
}
|
||||
else
|
||||
{
|
||||
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
|
||||
SendInput(1, &ip, sizeof(INPUT));
|
||||
}
|
||||
|
||||
// return 1;
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/*
|
||||
Program obsługi portu COM i innych na potrzeby sterownika MWDevice
|
||||
(oraz innych wykorzystujących komunikację przez port COM)
|
||||
dla Symulatora Pojazdów Szynowych MaSzyna
|
||||
author: Maciej Witek 2016
|
||||
Autor nie ponosi odpowiedzialności za niewłaciwe używanie lub działanie programu!
|
||||
*/
|
||||
|
||||
#ifndef MWDH
|
||||
#define MWDH
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#define BYTETOWRITE 31 // ilość bajtów przesyłanych z MaSzyny
|
||||
#define BYTETOREAD 16 // ilość bajtów przesyłanych do MaSzyny
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
class TMWDComm
|
||||
{
|
||||
private:
|
||||
int MWDTime; //
|
||||
char lastStateData[6], maskData[6], maskSwitch[6], bitSwitch[6];
|
||||
int bocznik, nastawnik, kierunek;
|
||||
char bnkMask;
|
||||
|
||||
bool ReadData(); //BYTE *pReadDataBuff);
|
||||
bool SendData(); //BYTE *pWriteDataBuff);
|
||||
void CheckData(); //sprawdzanie zmian wejść i kontrola mazaków HASLERA
|
||||
void KeyBoard(int key, bool s);
|
||||
|
||||
//void CheckData2();
|
||||
|
||||
bool bRysik1H;
|
||||
bool bRysik1L;
|
||||
bool bRysik2H;
|
||||
bool bRysik2L;
|
||||
|
||||
public:
|
||||
bool Open(); // Otwarcie portu
|
||||
bool Close(); // Zamknięcie portu
|
||||
bool Run(); // Obsługa portu
|
||||
bool GetMWDState(); // sprawdź czy port jest otwarty, 0 zamknięty, 1 otwarty
|
||||
|
||||
// zmienne do rysików HASLERA
|
||||
bool bSHPstate;
|
||||
bool bPrzejazdSHP;
|
||||
bool bKabina1;
|
||||
bool bKabina2;
|
||||
bool bHamowanie;
|
||||
bool bCzuwak;
|
||||
|
||||
unsigned int uiAnalog[4]; // trzymanie danych z wejść analogowych
|
||||
|
||||
BYTE ReadDataBuff[BYTETOREAD+2]; //17]; // bufory danych
|
||||
BYTE WriteDataBuff[BYTETOWRITE+2]; //31];
|
||||
|
||||
TMWDComm(); // konstruktor
|
||||
~TMWDComm(); // destruktor
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
INFO - wpisy do eu07.ini:
|
||||
|
||||
mwdmasterenable yes // włącz MWD (master MWD Enable)
|
||||
mwddebugenable yes // włącz logowanie
|
||||
mwddebugmode 4 // tryb debugowania (które logi)
|
||||
|
||||
mwdcomportname COM3 // nazwa portu
|
||||
mwdbaudrate 500000 // prędkość transmisji
|
||||
|
||||
mwdinputenable yes // włącz wejścia (przyciski, przełączniki)
|
||||
mwdbreakenable yes // włącz hamulce (wejścia analogowe)
|
||||
|
||||
mwdmainbreakconfig 0 1023 // konfiguracja kranu zespolonego -> min, max (położenie kranu - odczyt z ADC)
|
||||
mwdlocbreakconfig 0 1023 // konfiguracja kranu maszynisty -> min, max (położenie kranu - odczyt z ADC)
|
||||
mwdanalogin2config 0 1023
|
||||
mwdanalogin2config 0 1023
|
||||
|
||||
mwdmaintankpress 0.9 1023 // max ciśnienie w zbiorniku głownym i rozdzielczość
|
||||
mwdmainpipepress 0.7 1023 // max ciśnienie w przewodzie głównym i rozdzielczość
|
||||
mwdbreakpress 0.5 1023 // max ciśnienie w cylindrach hamulcowych i rozdzielczość
|
||||
|
||||
mwdhivoltmeter 4000 1023 // max napięcie na woltomierzu WN
|
||||
mwdhiampmeter 800 1023 // max prąd amperomierza WN
|
||||
|
||||
mwddivider 5 // dzielnik - czym większy tym rzadziej czyta diwajs
|
||||
*/
|
||||
9
EU07.cpp
9
EU07.cpp
@@ -33,6 +33,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
|
||||
#include "Timer.h"
|
||||
#include "resource.h"
|
||||
#include "uilayer.h"
|
||||
#include "uart.h"
|
||||
|
||||
#pragma comment (lib, "glu32.lib")
|
||||
#pragma comment (lib, "dsound.lib")
|
||||
@@ -50,7 +51,7 @@ keyboard_input Keyboard;
|
||||
mouse_input Mouse;
|
||||
gamepad_input Gamepad;
|
||||
glm::dvec2 mouse_pickmodepos; // stores last mouse position in control picking mode
|
||||
|
||||
std::unique_ptr<uart_input> uart;
|
||||
}
|
||||
|
||||
void screenshot_save_thread( char *img )
|
||||
@@ -350,9 +351,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
sound_man = std::make_unique<sound_manager>();
|
||||
|
||||
Global::pWorld = &World;
|
||||
|
||||
input::Keyboard.init();
|
||||
input::Mouse.init();
|
||||
input::Gamepad.init();
|
||||
if (Global::uart_conf.enable)
|
||||
input::uart = std::make_unique<uart_input>();
|
||||
|
||||
if( false == World.Init( window ) ) {
|
||||
ErrorLog( "Simulation setup failed" );
|
||||
@@ -393,6 +398,8 @@ int main(int argc, char *argv[])
|
||||
&& ( true == GfxRenderer.Render() ) ) {
|
||||
glfwPollEvents();
|
||||
input::Keyboard.poll();
|
||||
if (input::uart)
|
||||
input::uart->poll();
|
||||
if( true == Global::InputMouse ) { input::Mouse.poll(); }
|
||||
if( true == Global::InputGamepad ) { input::Gamepad.poll(); }
|
||||
}
|
||||
|
||||
136
Globals.cpp
136
Globals.cpp
@@ -166,24 +166,11 @@ int Global::iPoKeysPWM[7] = {0, 1, 2, 3, 4, 5, 6};
|
||||
bool Global::bnewAirCouplers = true;
|
||||
double Global::fTimeSpeed = 1.0; // przyspieszenie czasu, zmienna do testów
|
||||
bool Global::bHideConsole = false; // hunter-271211: ukrywanie konsoli
|
||||
|
||||
Global::uart_conf_t Global::uart_conf;
|
||||
|
||||
//randomizacja
|
||||
std::mt19937 Global::random_engine = std::mt19937(std::time(NULL));
|
||||
// maciek001: konfiguracja wstępna portu COM
|
||||
bool Global::bMWDmasterEnable = false; // główne włączenie portu!
|
||||
bool Global::bMWDdebugEnable = false; // włącz dodawanie do logu
|
||||
int Global::iMWDDebugMode = 0; // co ma wyświetlać w logu
|
||||
std::string Global::sMWDPortId = "COM1"; // nazwa portu z którego korzystamy
|
||||
unsigned long int Global::iMWDBaudrate = 9600; // prędkość transmisji danych
|
||||
bool Global::bMWDInputEnable = false; // włącz wejścia
|
||||
bool Global::bMWDBreakEnable = false; // włącz wejścia analogowe
|
||||
double Global::fMWDAnalogInCalib[4][2] = { { 0, 1023 },{ 0, 1023 },{ 0, 1023 },{ 0, 1023 } }; // wartość max potencjometru, wartość min potencjometru, rozdzielczość (max. wartość jaka może być)
|
||||
double Global::fMWDzg[2] = { 0.9, 1023 };
|
||||
double Global::fMWDpg[2] = { 0.8, 1023 };
|
||||
double Global::fMWDph[2] = { 0.6, 1023 };
|
||||
double Global::fMWDvolt[2] = { 4000, 1023 };
|
||||
double Global::fMWDamp[2] = { 800, 1023 };
|
||||
double Global::fMWDlowVolt[2] = { 150, 1023 };
|
||||
int Global::iMWDdivider = 5;
|
||||
|
||||
opengl_light Global::DayLight;
|
||||
Global::soundmode_t Global::soundpitchmode = Global::linear;
|
||||
@@ -756,101 +743,32 @@ void Global::ConfigParse(cParser &Parser)
|
||||
Parser.getTokens();
|
||||
Parser >> Global::InputGamepad;
|
||||
}
|
||||
// maciek001: ustawienia MWD
|
||||
else if (token == "mwdmasterenable") { // główne włączenie maszyny!
|
||||
Parser.getTokens();
|
||||
Parser >> bMWDmasterEnable;
|
||||
if (bMWDdebugEnable) WriteLog("SerialPort Master Enable");
|
||||
}
|
||||
else if (token == "mwddebugenable") { // logowanie pracy
|
||||
Parser.getTokens();
|
||||
Parser >> bMWDdebugEnable;
|
||||
if (bMWDdebugEnable) WriteLog("MWD Debug Mode On");
|
||||
}
|
||||
else if (token == "mwddebugmode") { // co ma być debugowane?
|
||||
Parser.getTokens(1, false);
|
||||
Parser >> iMWDDebugMode;
|
||||
if (bMWDdebugEnable) WriteLog("Debug Mode = " + to_string(iMWDDebugMode));
|
||||
}
|
||||
else if (token == "mwdcomportname") { // nazwa portu COM
|
||||
Parser.getTokens();
|
||||
Parser >> sMWDPortId;
|
||||
if (bMWDdebugEnable) WriteLog("PortName " + sMWDPortId);
|
||||
}
|
||||
else if (token == "mwdbaudrate") { // prędkość transmisji danych
|
||||
Parser.getTokens(1, false);
|
||||
Parser >> iMWDBaudrate;
|
||||
if (bMWDdebugEnable) WriteLog("Baud rate = " + to_string((int)(iMWDBaudrate / 1000)) + (" kbps"));
|
||||
}
|
||||
else if (token == "mwdinputenable") { // włącz wejścia
|
||||
Parser.getTokens();
|
||||
Parser >> bMWDInputEnable;
|
||||
if (bMWDdebugEnable && bMWDInputEnable) WriteLog("MWD Input Enable");
|
||||
}
|
||||
else if (token == "mwdbreakenable") { // włącz obsługę hamulców
|
||||
Parser.getTokens();
|
||||
Parser >> bMWDBreakEnable;
|
||||
if (bMWDdebugEnable && bMWDBreakEnable) WriteLog("MWD Break Enable");
|
||||
}
|
||||
else if (token == "mwdmainbreakconfig") { // ustawienia hamulca zespolonego
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDAnalogInCalib[0][0] >> fMWDAnalogInCalib[0][1];
|
||||
if (bMWDdebugEnable) WriteLog("Main break settings: " + to_string(fMWDAnalogInCalib[0][0]) + (" ") + to_string(fMWDAnalogInCalib[0][1]));
|
||||
}
|
||||
else if (token == "mwdlocbreakconfig") { // ustawienia hamulca lokomotywy
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDAnalogInCalib[1][0] >> fMWDAnalogInCalib[1][1];
|
||||
if (bMWDdebugEnable) WriteLog("Locomotive break settings: " + to_string(fMWDAnalogInCalib[1][0]) + (" ") + to_string(fMWDAnalogInCalib[1][1]));
|
||||
}
|
||||
else if (token == "mwdanalogin1config") { // ustawienia hamulca zespolonego
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDAnalogInCalib[2][0] >> fMWDAnalogInCalib[2][1];
|
||||
if (bMWDdebugEnable) WriteLog("Analog input 1 settings: " + to_string(fMWDAnalogInCalib[2][0]) + (" ") + to_string(fMWDAnalogInCalib[2][1]));
|
||||
}
|
||||
else if (token == "mwdanalogin2config") { // ustawienia hamulca lokomotywy
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDAnalogInCalib[3][0] >> fMWDAnalogInCalib[3][1];
|
||||
if (bMWDdebugEnable) WriteLog("Analog input 2 settings: " + to_string(fMWDAnalogInCalib[3][0]) + (" ") + to_string(fMWDAnalogInCalib[3][1]));
|
||||
}
|
||||
else if (token == "mwdmaintankpress") { // max ciśnienie w zbiorniku głownym i rozdzielczość
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDzg[0] >> fMWDzg[1];
|
||||
if (bMWDdebugEnable) WriteLog("MainAirTank settings: " + to_string(fMWDzg[0]) + (" ") + to_string(fMWDzg[1]));
|
||||
}
|
||||
else if (token == "mwdmainpipepress") { // max ciśnienie w przewodzie głownym i rozdzielczość
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDpg[0] >> fMWDpg[1];
|
||||
if (bMWDdebugEnable) WriteLog("MainAirPipe settings: " + to_string(fMWDpg[0]) + (" ") + to_string(fMWDpg[1]));
|
||||
}
|
||||
else if (token == "mwdbreakpress") { // max ciśnienie w hamulcach i rozdzielczość
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDph[0] >> fMWDph[1];
|
||||
if (bMWDdebugEnable) WriteLog("AirPipe settings: " + to_string(fMWDph[0]) + (" ") + to_string(fMWDph[1]));
|
||||
}
|
||||
else if (token == "mwdhivoltmeter") { // max napięcie na woltomierzu WN
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDvolt[0] >> fMWDvolt[1];
|
||||
if (bMWDdebugEnable) WriteLog("VoltMeter settings: " + to_string(fMWDvolt[0]) + (" ") + to_string(fMWDvolt[1]));
|
||||
}
|
||||
else if (token == "mwdhiampmeter") {
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDamp[0] >> fMWDamp[1];
|
||||
if (bMWDdebugEnable) WriteLog("Amp settings: " + to_string(fMWDamp[0]) + (" ") + to_string(fMWDamp[1]));
|
||||
}
|
||||
else if (token == "mwdlowvoltmeter") {
|
||||
Parser.getTokens(2, false);
|
||||
Parser >> fMWDlowVolt[0] >> fMWDlowVolt[1];
|
||||
if (bMWDdebugEnable) WriteLog("Low VoltMeter settings: " + to_string(fMWDlowVolt[0]) + (" ") + to_string(fMWDlowVolt[1]));
|
||||
}
|
||||
else if (token == "mwddivider") {
|
||||
Parser.getTokens(1, false);
|
||||
Parser >> iMWDdivider;
|
||||
if (iMWDdivider == 0)
|
||||
else if (token == "uart")
|
||||
{
|
||||
WriteLog("Dzielnik nie może być równy ZERO! Ustawiam na 1!");
|
||||
iMWDdivider = 1;
|
||||
Parser.getTokens(3, false);
|
||||
Global::uart_conf.enable = true;
|
||||
Parser >> Global::uart_conf.port;
|
||||
Parser >> Global::uart_conf.baud;
|
||||
Parser >> Global::uart_conf.interval;
|
||||
Parser >> Global::uart_conf.updatetime;
|
||||
}
|
||||
if (bMWDdebugEnable) WriteLog("Divider = " + to_string(iMWDdivider));
|
||||
else if (token == "uarttune")
|
||||
{
|
||||
Parser.getTokens(14);
|
||||
Parser >> Global::uart_conf.mainbrakemin
|
||||
>> Global::uart_conf.mainbrakemax
|
||||
>> Global::uart_conf.localbrakemin
|
||||
>> Global::uart_conf.localbrakemax
|
||||
>> Global::uart_conf.tankmax
|
||||
>> Global::uart_conf.tankuart
|
||||
>> Global::uart_conf.pipemax
|
||||
>> Global::uart_conf.pipeuart
|
||||
>> Global::uart_conf.brakemax
|
||||
>> Global::uart_conf.brakeuart
|
||||
>> Global::uart_conf.hvmax
|
||||
>> Global::uart_conf.hvuart
|
||||
>> Global::uart_conf.currentmax
|
||||
>> Global::uart_conf.currentuart;
|
||||
}
|
||||
} while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile)
|
||||
// na koniec trochę zależności
|
||||
|
||||
42
Globals.h
42
Globals.h
@@ -293,6 +293,31 @@ class Global
|
||||
//randomizacja
|
||||
static std::mt19937 random_engine;
|
||||
|
||||
struct uart_conf_t
|
||||
{
|
||||
bool enable = false;
|
||||
std::string port;
|
||||
int baud;
|
||||
int interval;
|
||||
float updatetime;
|
||||
|
||||
float mainbrakemin = 0.0f;
|
||||
float mainbrakemax = 65535.0f;
|
||||
float localbrakemin = 0.0f;
|
||||
float localbrakemax = 65535.0f;
|
||||
float tankmax = 10.0f;
|
||||
float tankuart = 65535.0f;
|
||||
float pipemax = 10.0f;
|
||||
float pipeuart = 65535.0f;
|
||||
float brakemax = 10.0f;
|
||||
float brakeuart = 65535.0f;
|
||||
float hvmax = 100000.0f;
|
||||
float hvuart = 65535.0f;
|
||||
float currentmax = 10000.0f;
|
||||
float currentuart = 65535.0f;
|
||||
};
|
||||
static uart_conf_t uart_conf;
|
||||
|
||||
// metody
|
||||
static void TrainDelete(TDynamicObject *d);
|
||||
static void ConfigParse(cParser &parser);
|
||||
@@ -303,23 +328,6 @@ class Global
|
||||
static std::string Bezogonkow(std::string str, bool _ = false);
|
||||
static double Min0RSpeed(double vel1, double vel2);
|
||||
|
||||
// maciek001: zmienne dla MWD
|
||||
static bool bMWDmasterEnable; // główne włączenie portu COM
|
||||
static bool bMWDdebugEnable; // logowanie pracy
|
||||
static int iMWDDebugMode;
|
||||
static std::string sMWDPortId; // nazwa portu COM
|
||||
static unsigned long int iMWDBaudrate; // prędkość transmisji
|
||||
static bool bMWDInputEnable; // włącz wejścia
|
||||
static bool bMWDBreakEnable; // włącz wejścia analogowe (hamulce)
|
||||
static double fMWDAnalogInCalib[4][2]; // ustawienia kranów hamulca zespolonego i dodatkowego - min i max
|
||||
static double fMWDzg[2]; // max wartość wskazywana i max wartość generowana (rozdzielczość)
|
||||
static double fMWDpg[2];
|
||||
static double fMWDph[2];
|
||||
static double fMWDvolt[2];
|
||||
static double fMWDamp[2];
|
||||
static double fMWDlowVolt[2];
|
||||
static int iMWDdivider;
|
||||
|
||||
static opengl_light DayLight;
|
||||
|
||||
enum soundmode_t
|
||||
|
||||
235
Train.cpp
235
Train.cpp
@@ -824,8 +824,7 @@ void TTrain::OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Co
|
||||
if( ( Train->mvOccupied->BrakeCtrlPos == -1 )
|
||||
&& ( Train->mvOccupied->BrakeHandle == FVel6 )
|
||||
&& ( Train->DynamicObject->Controller != AIdriver )
|
||||
&& ( Global::iFeedbackMode != 4 )
|
||||
&& ( !( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) {
|
||||
&& ( Global::iFeedbackMode != 4 ) ) {
|
||||
// Odskakiwanie hamulce EP
|
||||
Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->BrakeCtrlPos + 1 );
|
||||
Train->keybrakecount = 0;
|
||||
@@ -856,8 +855,7 @@ void TTrain::OnCommand_trainbrakecharging( TTrain *Train, command_data const &Co
|
||||
if( ( Train->mvOccupied->BrakeCtrlPos == -1 )
|
||||
&& ( Train->mvOccupied->BrakeHandle == FVel6 )
|
||||
&& ( Train->DynamicObject->Controller != AIdriver )
|
||||
&& ( Global::iFeedbackMode != 4 )
|
||||
&& ( !( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) {
|
||||
&& ( Global::iFeedbackMode != 4 ) ) {
|
||||
// Odskakiwanie hamulce EP
|
||||
Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->BrakeCtrlPos + 1 );
|
||||
Train->keybrakecount = 0;
|
||||
@@ -1248,7 +1246,12 @@ void TTrain::OnCommand_alerteracknowledge( TTrain *Train, command_data const &Co
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command ) {
|
||||
void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command )
|
||||
{
|
||||
if (Command.desired_state == command_data::ON && Train->mvOccupied->Battery)
|
||||
return;
|
||||
if (Command.desired_state == command_data::OFF && !Train->mvOccupied->Battery)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
@@ -1289,7 +1292,19 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command ) {
|
||||
void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &cmd )
|
||||
{
|
||||
command_data Command = cmd;
|
||||
|
||||
if (Train->mvOccupied->PantSwitchType != "impulse")
|
||||
{
|
||||
if (Command.desired_state == Command.ON && Train->mvControlled->PantFrontUp)
|
||||
return;
|
||||
if (Command.desired_state == Command.OFF && !Train->mvControlled->PantFrontUp)
|
||||
return;
|
||||
}
|
||||
else if (Command.desired_state == Command.OFF)
|
||||
Command.action = GLFW_RELEASE;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
@@ -1369,7 +1384,18 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command ) {
|
||||
void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &cmd ) {
|
||||
command_data Command = cmd;
|
||||
|
||||
if (Train->mvOccupied->PantSwitchType != "impulse")
|
||||
{
|
||||
if (Command.desired_state == Command.ON && Train->mvControlled->PantRearUp)
|
||||
return;
|
||||
if (Command.desired_state == Command.OFF && !Train->mvControlled->PantRearUp)
|
||||
return;
|
||||
}
|
||||
else if (Command.desired_state == Command.OFF)
|
||||
Command.action = GLFW_RELEASE;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
@@ -1562,7 +1588,8 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// press or hold...
|
||||
if( Train->m_linebreakerstate == 0 ) {
|
||||
if ((Command.desired_state == command_data::TOGGLE && Train->m_linebreakerstate == 0)
|
||||
|| Command.desired_state == command_data::ON) {
|
||||
// ...to close the circuit
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// fresh press, start fresh closing delay calculation
|
||||
@@ -1609,9 +1636,10 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( Train->m_linebreakerstate == 1 ) {
|
||||
else if ((Command.desired_state == command_data::TOGGLE && Train->m_linebreakerstate == 1)
|
||||
|| Command.desired_state == command_data::OFF) {
|
||||
// ...to open the circuit
|
||||
if( true == Train->mvControlled->MainSwitch( false ) ) {
|
||||
Train->mvControlled->MainSwitch( false );
|
||||
|
||||
Train->m_linebreakerstate = -1;
|
||||
|
||||
@@ -1622,26 +1650,12 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
|
||||
}
|
||||
else if( Train->ggMainButton.SubModel != nullptr ) {
|
||||
// single two-state switch
|
||||
/*
|
||||
// NOTE: we don't have switch type definition for the line breaker switch
|
||||
// so for the time being we have hard coded "impulse" switches for all EMUs
|
||||
// TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz
|
||||
if( Train->mvControlled->TrainType == dt_EZT ) {
|
||||
// audio feedback
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggMainButton.UpdateValue( 1.0 );
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// play sound immediately when the switch is hit, not after release
|
||||
if( Train->fMainRelayTimer > 0.0f ) {
|
||||
Train->play_sound( Train->dsbRelay );
|
||||
@@ -1713,6 +1727,11 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->ConverterAllow && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->mvControlled->ConverterAllow && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( ( false == Train->mvControlled->ConverterAllow )
|
||||
@@ -1866,6 +1885,11 @@ void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Comm
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->CompressorAllow && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->mvControlled->CompressorAllow && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( false == Train->mvControlled->CompressorAllow ) {
|
||||
@@ -1945,8 +1969,8 @@ void TTrain::OnCommand_compressortogglelocal( TTrain *Train, command_data const
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &cmd ) {
|
||||
command_data Command = cmd;
|
||||
// TODO: don't rely on presense of 3d model to determine presence of the switch
|
||||
if( Train->ggStLinOffButton.SubModel == nullptr ) {
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -1954,6 +1978,17 @@ void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &C
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->StLinSwitchType == "toggle")
|
||||
{
|
||||
if (Command.desired_state == Command.ON && Train->mvControlled->StLinSwitchOff)
|
||||
return;
|
||||
if (Command.desired_state == Command.OFF && !Train->mvControlled->StLinSwitchOff)
|
||||
return;
|
||||
}
|
||||
else if (Command.desired_state == Command.OFF)
|
||||
Command.action = GLFW_RELEASE;
|
||||
|
||||
// NOTE: because we don't have modeled actual circuits this is a simplification of the real mechanics
|
||||
// namely, pressing the button will flip it in the entire unit, which isn't exactly physically possible
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -2064,7 +2099,12 @@ void TTrain::OnCommand_motordisconnect( TTrain *Train, command_data const &Comma
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ) {
|
||||
void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command )
|
||||
{
|
||||
if (Train->mvControlled->Imax < Train->mvControlled->ImaxHi && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
if (!(Train->mvControlled->Imax < Train->mvControlled->ImaxHi) && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
@@ -2119,9 +2159,16 @@ void TTrain::OnCommand_headlighttoggleleft( TTrain *Train, command_data const &C
|
||||
0 :
|
||||
1 );
|
||||
|
||||
bool current_state = (bool)(Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left);
|
||||
|
||||
if (Command.desired_state == command_data::ON && current_state)
|
||||
return;
|
||||
if (Command.desired_state == command_data::OFF && !current_state)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) == 0 ) {
|
||||
if( !current_state ) {
|
||||
// turn on
|
||||
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left;
|
||||
// visual feedback
|
||||
@@ -2152,9 +2199,16 @@ void TTrain::OnCommand_headlighttoggleright( TTrain *Train, command_data const &
|
||||
0 :
|
||||
1 );
|
||||
|
||||
bool current_state = (bool)(Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right);
|
||||
|
||||
if (Command.desired_state == command_data::ON && current_state)
|
||||
return;
|
||||
if (Command.desired_state == command_data::OFF && !current_state)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right ) == 0 ) {
|
||||
if( !current_state ) {
|
||||
// turn on
|
||||
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right;
|
||||
// visual feedback
|
||||
@@ -2185,9 +2239,16 @@ void TTrain::OnCommand_headlighttoggleupper( TTrain *Train, command_data const &
|
||||
0 :
|
||||
1 );
|
||||
|
||||
bool current_state = (bool)(Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper);
|
||||
|
||||
if (Command.desired_state == command_data::ON && current_state)
|
||||
return;
|
||||
if (Command.desired_state == command_data::OFF && !current_state)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper ) == 0 ) {
|
||||
if( !current_state ) {
|
||||
// turn on
|
||||
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper;
|
||||
// visual feedback
|
||||
@@ -2452,6 +2513,11 @@ void TTrain::OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &C
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->DynamicObject->DimHeadlights && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->DynamicObject->DimHeadlights && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( false == Train->DynamicObject->DimHeadlights ) {
|
||||
@@ -2509,6 +2575,11 @@ void TTrain::OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->bCabLightDim && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->bCabLightDim && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( false == Train->bCabLightDim ) {
|
||||
@@ -2564,6 +2635,11 @@ void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->Heating && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->mvControlled->Heating && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( false == Train->mvControlled->Heating ) {
|
||||
@@ -3719,20 +3795,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
/// skakanie zapewnia mechanika
|
||||
/// napędu
|
||||
}
|
||||
|
||||
if (Global::bMWDmasterEnable) // pobieranie danych dla pulpitu port (COM)
|
||||
{
|
||||
Console::ValueSet(0, mvOccupied->Compressor); // zbiornik główny
|
||||
Console::ValueSet(1, mvOccupied->PipePress); // przewód główny
|
||||
Console::ValueSet(2, mvOccupied->BrakePress); // cylinder hamulcowy
|
||||
Console::ValueSet(3, fHVoltage); // woltomierz wysokiego napięcia
|
||||
Console::ValueSet(4, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]);
|
||||
// pierwszy amperomierz; dla EZT prąd całkowity
|
||||
Console::ValueSet(5, fHCurrent[2]); // drugi amperomierz 2
|
||||
Console::ValueSet(6, fHCurrent[3]); // drugi amperomierz 3
|
||||
Console::ValueSet(7, fTachoVelocity);
|
||||
//Console::ValueSet(8, mvControlled->BatteryVoltage); // jeszcze nie pora ;)
|
||||
}
|
||||
#endif
|
||||
|
||||
// hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia
|
||||
@@ -4654,7 +4716,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
#ifdef _WIN32
|
||||
if (DynamicObject->Mechanik ?
|
||||
(DynamicObject->Mechanik->AIControllFlag ? false :
|
||||
(Global::iFeedbackMode == 4 || (Global::bMWDmasterEnable && Global::bMWDBreakEnable))) :
|
||||
(Global::iFeedbackMode == 4)) :
|
||||
false) // nie blokujemy AI
|
||||
{ // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba
|
||||
// Firleju: dlatego kasujemy i zastepujemy funkcją w Console
|
||||
@@ -4663,7 +4725,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
double b = Console::AnalogCalibrateGet(0);
|
||||
b = b * 8.0 - 2.0;
|
||||
b = clamp<double>( b, -2.0, mvOccupied->BrakeCtrlPosNo ); // przycięcie zmiennej do granic
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FV4a break position = " + to_string(b));
|
||||
ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia
|
||||
mvOccupied->BrakeLevelSet(b);
|
||||
}
|
||||
@@ -4672,7 +4733,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
double b = Console::AnalogCalibrateGet(0);
|
||||
b = b * 7.0 - 1.0;
|
||||
b = clamp<double>( b, -1.0, mvOccupied->BrakeCtrlPosNo ); // przycięcie zmiennej do granic
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FVel6 break position = " + to_string(b));
|
||||
ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia
|
||||
mvOccupied->BrakeLevelSet(b);
|
||||
}
|
||||
@@ -4690,8 +4750,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
if( ( DynamicObject->Mechanik != nullptr )
|
||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI
|
||||
&& ( mvOccupied->BrakeLocHandle == FD1 )
|
||||
&& ( ( Global::iFeedbackMode == 4 )
|
||||
|| ( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) {
|
||||
&& ( ( Global::iFeedbackMode == 4 ) ) ) {
|
||||
// Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba
|
||||
// Firleju: dlatego kasujemy i zastepujemy funkcją w Console
|
||||
auto const b = clamp<double>(
|
||||
@@ -4700,10 +4759,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
ManualBrakePosNo );
|
||||
ggLocalBrake.UpdateValue( b ); // przesów bez zaokrąglenia
|
||||
mvOccupied->LocalBrakePos = int( 1.09 * b ); // sposób zaokrąglania jest do ustalenia
|
||||
if( ( true == Global::bMWDdebugEnable )
|
||||
&& ( ( Global::iMWDDebugMode & 4 ) != 0 ) ) {
|
||||
WriteLog( "FD1 break position = " + to_string( b ) );
|
||||
}
|
||||
}
|
||||
else // standardowa prodedura z kranem powiązanym z klawiaturą
|
||||
#endif
|
||||
@@ -7419,3 +7474,75 @@ TTrain::play_sound( sound* Sound, sound* Fallbacksound, float gain ) {
|
||||
play_sound( Fallbacksound, gain );
|
||||
}
|
||||
|
||||
float TTrain::get_tacho()
|
||||
{
|
||||
return fTachoVelocity;
|
||||
}
|
||||
|
||||
float TTrain::get_tank_pressure()
|
||||
{
|
||||
return mvOccupied->Compressor;
|
||||
}
|
||||
|
||||
float TTrain::get_pipe_pressure()
|
||||
{
|
||||
return mvOccupied->PipePress;
|
||||
}
|
||||
|
||||
float TTrain::get_brake_pressure()
|
||||
{
|
||||
return mvOccupied->BrakePress;
|
||||
}
|
||||
|
||||
float TTrain::get_hv_voltage()
|
||||
{
|
||||
return fHVoltage;
|
||||
}
|
||||
|
||||
std::array<float, 3> TTrain::get_current()
|
||||
{
|
||||
return { fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1], fHCurrent[2], fHCurrent[3] };
|
||||
}
|
||||
|
||||
bool TTrain::get_alarm()
|
||||
{
|
||||
return (TestFlag(mvOccupied->SecuritySystem.Status, s_CAalarm) ||
|
||||
TestFlag(mvOccupied->SecuritySystem.Status, s_SHPalarm));
|
||||
}
|
||||
|
||||
void TTrain::set_mainctrl(int pos)
|
||||
{
|
||||
if (pos < mvControlled->MainCtrlPos)
|
||||
mvControlled->DecMainCtrl(1);
|
||||
else if (pos > mvControlled->MainCtrlPos)
|
||||
mvControlled->IncMainCtrl(1);
|
||||
}
|
||||
|
||||
void TTrain::set_scndctrl(int pos)
|
||||
{
|
||||
if (pos < mvControlled->ScndCtrlPos)
|
||||
mvControlled->DecScndCtrl(1);
|
||||
else if (pos > mvControlled->ScndCtrlPos)
|
||||
mvControlled->IncScndCtrl(1);
|
||||
}
|
||||
|
||||
void TTrain::set_trainbrake(float val)
|
||||
{
|
||||
val = std::min(1.0f, std::max(0.0f, val));
|
||||
float min = mvControlled->Handle->GetPos(bh_MIN);
|
||||
float max = mvControlled->Handle->GetPos(bh_MAX);
|
||||
mvControlled->BrakeLevelSet(min + val * (max - min));
|
||||
}
|
||||
|
||||
void TTrain::set_localbrake(float val)
|
||||
{
|
||||
val = std::min(1.0f, std::max(0.0f, val));
|
||||
float min = 0.0f;
|
||||
float max = (float)LocalBrakePosNo;
|
||||
mvControlled->LocalBrakePos = std::round(min + val * (max - min));
|
||||
}
|
||||
|
||||
int TTrain::get_drive_direction()
|
||||
{
|
||||
return mvOccupied->ActiveDir * mvOccupied->CabNo;
|
||||
}
|
||||
|
||||
14
Train.h
14
Train.h
@@ -493,5 +493,19 @@ public: // reszta może by?publiczna
|
||||
inline TMoverParameters *Controlled() { return mvControlled; };
|
||||
void DynamicSet(TDynamicObject *d);
|
||||
void Silence();
|
||||
|
||||
float get_tacho();
|
||||
float get_tank_pressure();
|
||||
float get_pipe_pressure();
|
||||
float get_brake_pressure();
|
||||
float get_hv_voltage();
|
||||
std::array<float, 3> get_current();
|
||||
bool get_alarm();
|
||||
int get_drive_direction();
|
||||
|
||||
void set_mainctrl(int);
|
||||
void set_scndctrl(int);
|
||||
void set_trainbrake(float);
|
||||
void set_localbrake(float);
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -17,5 +17,7 @@ cmake ../.. -T v140_xp ^
|
||||
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
|
||||
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win32/libsndfile-1.lib ^
|
||||
-DLUAJIT_INCLUDE_DIR=%DEPS_DIR%/luajit/include ^
|
||||
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win32/lua51.lib
|
||||
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win32/lua51.lib ^
|
||||
-Dlibserialport_INCLUDE_DIR=%DEPS_DIR%/libserialport/include ^
|
||||
-Dlibserialport_LIBRARY=%DEPS_DIR%/libserialport/lib/win32/libserialport-0.lib
|
||||
popd
|
||||
@@ -17,5 +17,7 @@ cmake ../.. -A x64 ^
|
||||
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
|
||||
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win64/libsndfile-1.lib ^
|
||||
-DLUAJIT_INCLUDE_DIR=%DEPS_DIR%/luajit/include ^
|
||||
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win64/lua51.lib
|
||||
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win64/lua51.lib ^
|
||||
-Dlibserialport_INCLUDE_DIR=%DEPS_DIR%/libserialport/include ^
|
||||
-Dlibserialport_LIBRARY=%DEPS_DIR%/libserialport/lib/win64/libserialport-0.lib
|
||||
popd
|
||||
@@ -1,2 +1,2 @@
|
||||
powershell "$wc = New-Object System.Net.WebClient; $wc.DownloadFile(\"https://milek7.pl/.stuff/eu07exe/builddep3.zip\", \"%cd%\deps_win.zip\")"
|
||||
powershell "$wc = New-Object System.Net.WebClient; $wc.DownloadFile(\"https://milek7.pl/.stuff/eu07exe/builddep4.zip\", \"%cd%\deps_win.zip\")"
|
||||
powershell "$s = New-Object -ComObject shell.application; $z = $s.Namespace(\"%cd%\deps_win.zip\"); foreach ($i in $z.items()) { $s.Namespace(\"%cd%\").CopyHere($i) }"
|
||||
|
||||
@@ -174,7 +174,9 @@ command_queue::pop( command_data &Command, std::size_t const Recipient ) {
|
||||
}
|
||||
|
||||
void
|
||||
command_relay::post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const {
|
||||
command_relay::post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2,
|
||||
int const Action, std::uint16_t const Recipient,
|
||||
command_data::desired_state_t state) const {
|
||||
|
||||
auto const &command = simulation::Commands_descriptions[ static_cast<std::size_t>( Command ) ];
|
||||
if( ( command.target == command_target::vehicle )
|
||||
@@ -191,7 +193,7 @@ command_relay::post( user_command const Command, std::uint64_t const Param1, std
|
||||
Action,
|
||||
Param1,
|
||||
Param2,
|
||||
Timer::GetDeltaTime() },
|
||||
state, Timer::GetDeltaTime() },
|
||||
static_cast<std::size_t>( command.target ) | Recipient );
|
||||
/*
|
||||
#ifdef _DEBUG
|
||||
|
||||
11
command.h
11
command.h
@@ -169,6 +169,13 @@ struct command_data {
|
||||
int action; // press, repeat or release
|
||||
std::uint64_t param1;
|
||||
std::uint64_t param2;
|
||||
enum desired_state_t
|
||||
{
|
||||
TOGGLE,
|
||||
OFF,
|
||||
ON
|
||||
};
|
||||
desired_state_t desired_state;
|
||||
double time_delta;
|
||||
};
|
||||
|
||||
@@ -218,7 +225,9 @@ public:
|
||||
// posts specified command for the specified recipient
|
||||
// TODO: replace uint16_t with recipient handle, based on item id
|
||||
void
|
||||
post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const;
|
||||
post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2,
|
||||
int const Action, std::uint16_t const Recipient,
|
||||
command_data::desired_state_t state = command_data::TOGGLE ) const;
|
||||
private:
|
||||
// types
|
||||
// members
|
||||
|
||||
173
uart.cpp
Normal file
173
uart.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "stdafx.h"
|
||||
#include "uart.h"
|
||||
#include "Globals.h"
|
||||
#include "World.h"
|
||||
#include "Train.h"
|
||||
#include "Logs.h"
|
||||
|
||||
uart_input::uart_input()
|
||||
{
|
||||
conf = Global::uart_conf;
|
||||
|
||||
if (sp_get_port_by_name(conf.port.c_str(), &port) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot find specified port");
|
||||
|
||||
if (sp_open(port, SP_MODE_READ_WRITE) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot open port");
|
||||
|
||||
if (sp_set_baudrate(port, conf.baud) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot set baudrate");
|
||||
|
||||
if (sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot set flowcontrol");
|
||||
|
||||
if (sp_flush(port, SP_BUF_BOTH) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot flush");
|
||||
|
||||
old_packet.fill(0);
|
||||
last_update = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
uart_input::~uart_input()
|
||||
{
|
||||
sp_close(port);
|
||||
sp_free_port(port);
|
||||
}
|
||||
|
||||
#define SPLIT_INT16(x) (uint8_t)x, (uint8_t)(x >> 8)
|
||||
|
||||
void uart_input::poll()
|
||||
{
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
if (std::chrono::duration<float>(now - last_update).count() < conf.updatetime)
|
||||
return;
|
||||
last_update = now;
|
||||
|
||||
TTrain *t = Global::pWorld->train();
|
||||
|
||||
sp_return ret;
|
||||
|
||||
if (sp_input_waiting(port) >= 16)
|
||||
{
|
||||
std::array<uint8_t, 16> buffer;
|
||||
ret = sp_blocking_read(port, (void*)buffer.data(), buffer.size(), 0);
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("uart: failed to read from port");
|
||||
|
||||
sp_drain(port);
|
||||
data_pending = false;
|
||||
|
||||
for (auto entry : input_bits)
|
||||
{
|
||||
input_type_t type = std::get<2>(entry);
|
||||
|
||||
size_t byte = std::get<0>(entry) / 8;
|
||||
size_t bit = std::get<0>(entry) % 8;
|
||||
|
||||
bool state = (bool)(buffer[byte] & (1 << bit));
|
||||
|
||||
bool repeat = (type == impulse_r ||
|
||||
type == impulse_r_off ||
|
||||
type == impulse_r_on);
|
||||
|
||||
bool changed = (state != (bool)(old_packet[byte] & (1 << bit)));
|
||||
|
||||
if (!changed && !(repeat && state))
|
||||
continue;
|
||||
|
||||
int action;
|
||||
command_data::desired_state_t desired_state;
|
||||
|
||||
if (type == toggle)
|
||||
{
|
||||
action = GLFW_PRESS;
|
||||
desired_state = state ? command_data::ON : command_data::OFF;
|
||||
}
|
||||
else if (type == impulse_r_on)
|
||||
{
|
||||
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
|
||||
desired_state = command_data::ON;
|
||||
}
|
||||
else if (type == impulse_r_off)
|
||||
{
|
||||
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
|
||||
desired_state = command_data::OFF;
|
||||
}
|
||||
else if (type == impulse || type == impulse_r)
|
||||
{
|
||||
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
|
||||
desired_state = command_data::TOGGLE;
|
||||
}
|
||||
|
||||
relay.post(std::get<1>(entry), 0, 0, action, 0, desired_state);
|
||||
}
|
||||
|
||||
int mainctrl = buffer[6];
|
||||
int scndctrl = buffer[7];
|
||||
float trainbrake = (float)(((uint16_t)buffer[8] | ((uint16_t)buffer[9] << 8)) - conf.mainbrakemin) / (conf.mainbrakemax - conf.mainbrakemin);
|
||||
float localbrake = (float)(((uint16_t)buffer[10] | ((uint16_t)buffer[11] << 8)) - conf.mainbrakemin) / (conf.localbrakemax - conf.localbrakemin);
|
||||
|
||||
t->set_mainctrl(mainctrl);
|
||||
t->set_scndctrl(scndctrl);
|
||||
t->set_trainbrake(trainbrake);
|
||||
t->set_localbrake(localbrake);
|
||||
|
||||
old_packet = buffer;
|
||||
}
|
||||
|
||||
if (!data_pending && sp_output_waiting(port) == 0)
|
||||
{
|
||||
// TODO: ugly! move it into structure like input_bits
|
||||
|
||||
uint8_t buzzer = (uint8_t)t->get_alarm();
|
||||
uint8_t tacho = (uint8_t)t->get_tacho();
|
||||
uint16_t tank_press = (uint16_t)std::min(conf.tankuart, t->get_tank_pressure() / conf.tankmax * conf.tankuart);
|
||||
uint16_t pipe_press = (uint16_t)std::min(conf.pipeuart, t->get_pipe_pressure() / conf.pipemax * conf.pipeuart);
|
||||
uint16_t brake_press = (uint16_t)std::min(conf.brakeuart, t->get_brake_pressure() / conf.brakemax * conf.brakeuart);
|
||||
uint16_t hv_voltage = (uint16_t)std::min(conf.hvuart, t->get_hv_voltage() / conf.hvmax * conf.hvuart);
|
||||
auto current = t->get_current();
|
||||
uint16_t current1 = (uint16_t)std::min(conf.currentuart, current[0]) / conf.currentmax * conf.currentuart;
|
||||
uint16_t current2 = (uint16_t)std::min(conf.currentuart, current[1]) / conf.currentmax * conf.currentuart;
|
||||
uint16_t current3 = (uint16_t)std::min(conf.currentuart, current[2]) / conf.currentmax * conf.currentuart;
|
||||
|
||||
std::array<uint8_t, 31> buffer =
|
||||
{
|
||||
0, 0, //byte 0-1
|
||||
tacho, //byte 2
|
||||
0, 0, 0, 0, 0, 0, //byte 3-8
|
||||
SPLIT_INT16(brake_press), //byte 9-10
|
||||
SPLIT_INT16(pipe_press), //byte 11-12
|
||||
SPLIT_INT16(tank_press), //byte 13-14
|
||||
SPLIT_INT16(hv_voltage), //byte 15-16
|
||||
SPLIT_INT16(current1), //byte 17-18
|
||||
SPLIT_INT16(current2), //byte 19-20
|
||||
SPLIT_INT16(current3), //byte 21-22
|
||||
0, 0, 0, 0, 0, 0, 0, 0 //byte 23-30
|
||||
};
|
||||
|
||||
buffer[4] |= t->btLampkaOpory.b() << 1;
|
||||
buffer[4] |= t->btLampkaWysRozr.b() << 2;
|
||||
|
||||
buffer[6] |= t->btLampkaOgrzewanieSkladu.b() << 0;
|
||||
buffer[6] |= t->btLampkaOpory.b() << 1;
|
||||
buffer[6] |= t->btLampkaPoslizg.b() << 2;
|
||||
buffer[6] |= t->btLampkaCzuwaka.b() << 6;
|
||||
buffer[6] |= t->btLampkaSHP.b() << 7;
|
||||
|
||||
buffer[7] |= t->btLampkaStyczn.b() << 0;
|
||||
buffer[7] |= t->btLampkaNadmPrzetw.b() << 2;
|
||||
buffer[7] |= t->btLampkaNadmSil.b() << 4;
|
||||
buffer[7] |= t->btLampkaWylSzybki.b() << 5;
|
||||
buffer[7] |= t->btLampkaNadmSpr.b() << 6;
|
||||
|
||||
buffer[8] |= buzzer << 7;
|
||||
|
||||
sp_flush(port, SP_BUF_INPUT); // flush input buffer in preparation for reply packet
|
||||
|
||||
ret = sp_blocking_write(port, (void*)buffer.data(), buffer.size(), 0);
|
||||
if (ret != buffer.size())
|
||||
throw std::runtime_error("uart: failed to write to port");
|
||||
|
||||
data_pending = true;
|
||||
}
|
||||
}
|
||||
58
uart.h
Normal file
58
uart.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include <libserialport.h>
|
||||
#include "command.h"
|
||||
#include "Globals.h"
|
||||
|
||||
class uart_input
|
||||
{
|
||||
enum input_type_t
|
||||
{
|
||||
toggle,
|
||||
impulse,
|
||||
impulse_r,
|
||||
impulse_r_on,
|
||||
impulse_r_off
|
||||
};
|
||||
|
||||
std::array<std::tuple<size_t, user_command, input_type_t>, 23> input_bits =
|
||||
{
|
||||
std::make_tuple(1, user_command::linebreakertoggle, impulse_r_off),
|
||||
std::make_tuple(2, user_command::linebreakertoggle, impulse_r_on),
|
||||
std::make_tuple(3, user_command::motoroverloadrelayreset, impulse),
|
||||
std::make_tuple(5, user_command::converteroverloadrelayreset, impulse),
|
||||
std::make_tuple(6, user_command::motorconnectorsopen, toggle),
|
||||
std::make_tuple(7, user_command::alerteracknowledge, impulse_r),
|
||||
|
||||
std::make_tuple(9, user_command::convertertoggle, toggle),
|
||||
std::make_tuple(10, user_command::compressortoggle, toggle),
|
||||
std::make_tuple(11, user_command::sandboxactivate, impulse),
|
||||
std::make_tuple(12, user_command::heatingtoggle, toggle),
|
||||
|
||||
std::make_tuple(15, user_command::motoroverloadrelaythresholdtoggle, toggle),
|
||||
std::make_tuple(16, user_command::pantographtogglefront, toggle),
|
||||
std::make_tuple(17, user_command::pantographtogglerear, toggle),
|
||||
std::make_tuple(18, user_command::wheelspinbrakeactivate, impulse),
|
||||
std::make_tuple(19, user_command::headlightsdimtoggle, toggle),
|
||||
std::make_tuple(20, user_command::interiorlightdimtoggle, toggle),
|
||||
std::make_tuple(21, user_command::independentbrakebailoff, impulse),
|
||||
std::make_tuple(22, user_command::hornhighactivate, impulse),
|
||||
std::make_tuple(23, user_command::hornlowactivate, impulse),
|
||||
|
||||
std::make_tuple(24, user_command::batterytoggle, toggle),
|
||||
std::make_tuple(25, user_command::headlighttoggleleft, toggle),
|
||||
std::make_tuple(26, user_command::headlighttoggleupper, toggle),
|
||||
std::make_tuple(27, user_command::headlighttoggleright, toggle)
|
||||
};
|
||||
|
||||
sp_port *port = nullptr;
|
||||
command_relay relay;
|
||||
std::array<uint8_t, 16> old_packet;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> last_update;
|
||||
Global::uart_conf_t conf;
|
||||
bool data_pending = false;
|
||||
|
||||
public:
|
||||
uart_input();
|
||||
~uart_input();
|
||||
void poll();
|
||||
};
|
||||
Reference in New Issue
Block a user