moved to shstk
@@ -1,76 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(kx_utils)
|
||||
if (POLICY CMP0017)
|
||||
cmake_policy(SET CMP0017 NEW)
|
||||
endif()
|
||||
if (NOT LIBPROJECT)
|
||||
find_package(PIP REQUIRED)
|
||||
endif ()
|
||||
if (MINGW)
|
||||
find_package(MinGW REQUIRED)
|
||||
endif()
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES})
|
||||
set(KX_PULT_NAME "kx_pult")
|
||||
option(KX_PULT "Build ${KX_PULT_NAME}" 1)
|
||||
option(LIB "System install" 1)
|
||||
option(DEBUG "Build with -g3" 0)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall")
|
||||
if (DEBUG)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
|
||||
endif()
|
||||
set(CPPS_UTILS "kx_coeffs.cpp" "piprotocol.cpp")
|
||||
set(HDRS_UTILS "kx_coeffs.h" "kx_protocol_x.h" "kx_protocol_c.h" "piprotocol.h")
|
||||
if (DEFINED ENV{QNX_HOST})
|
||||
add_library(${PROJECT_NAME} STATIC ${CPPS_UTILS})
|
||||
else()
|
||||
add_library(${PROJECT_NAME} SHARED ${CPPS_UTILS})
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} ${PIP_LIBRARY})
|
||||
message(STATUS "Building ${PROJECT_NAME}")
|
||||
if (NOT DEFINED ENV{QNX_HOST})
|
||||
if (KX_PULT)
|
||||
find_package(Qt4 REQUIRED)
|
||||
find_package(QAD REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${QT_INCLUDES} ${QAD_INCLUDES})
|
||||
set(CPPS "kx_pult.cpp" "kx_pult.h" "kx_pult.ui" "main_kx_pult.cpp")
|
||||
set(MOCS "kx_pult.h")
|
||||
file(GLOB UIS "*.ui")
|
||||
file(GLOB RES "*.qrc")
|
||||
qt4_wrap_cpp(CMOCS ${MOCS} OPTIONS -nw)
|
||||
qt4_wrap_ui(CUIS ${UIS})
|
||||
qt4_add_resources(RESS ${RES})
|
||||
add_executable(${KX_PULT_NAME} WIN32 ${CPPS} ${CMOCS} ${CUIS} ${RESS} ${MOCS})
|
||||
set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_LIBRARIES} ${PIP_LIBRARY} qad_graphic4 qad_utils4 qad_widgets4)
|
||||
target_link_libraries(${KX_PULT_NAME} ${LIBS} ${PROJECT_NAME})
|
||||
endif()
|
||||
endif()
|
||||
if (LIB)
|
||||
list(APPEND _ALL_TARGETS ${PROJECT_NAME})
|
||||
set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE)
|
||||
if (WIN32)
|
||||
set(CMAKE_INSTALL_PREFIX ${MINGW_DIR})
|
||||
install(FILES ${HDRS_UTILS} DESTINATION ${MINGW_INCLUDE})
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION ${MINGW_LIB})
|
||||
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN})
|
||||
else()
|
||||
if (DEFINED ANDROID_PLATFORM)
|
||||
set(CMAKE_INSTALL_PREFIX ${ANDROID_SYSTEM_LIBRARY_PATH}/usr)
|
||||
else()
|
||||
set(CMAKE_INSTALL_PREFIX /usr/local)
|
||||
endif()
|
||||
install(FILES ${HDRS_UTILS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
endif()
|
||||
message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
|
||||
else()
|
||||
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
|
||||
install(FILES ${HDRS_UTILS} DESTINATION include)
|
||||
message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"")
|
||||
endif()
|
||||
if (NOT DEFINED ENV{QNX_HOST})
|
||||
if (KX_PULT)
|
||||
install(TARGETS ${KX_PULT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,4 +0,0 @@
|
||||
#! /bin/bash
|
||||
VERBOSE=1 make clean
|
||||
rm -rvf CMakeFiles
|
||||
rm -vf CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *.user* *~ *cxx moc_* ui_* qrc_* *.o
|
||||
@@ -1,4 +0,0 @@
|
||||
#make clean
|
||||
del /q /f /s CMakeFiles
|
||||
rmdir /q /s CMakeFiles
|
||||
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *.user* *~ *cxx moc_* ui_* qrc_* *.o *.exe *.a *.dll *.lib core *.qrc.depends
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 158 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1005 B |
|
Before Width: | Height: | Size: 717 B |
|
Before Width: | Height: | Size: 813 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1017 B |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 563 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 644 B |
|
Before Width: | Height: | Size: 802 B |
|
Before Width: | Height: | Size: 485 B |
|
Before Width: | Height: | Size: 640 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 634 B |
|
Before Width: | Height: | Size: 544 B |
|
Before Width: | Height: | Size: 529 B |
|
Before Width: | Height: | Size: 571 B |
|
Before Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 579 B |
|
Before Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 639 B |
|
Before Width: | Height: | Size: 448 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 564 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 694 B |
|
Before Width: | Height: | Size: 658 B |
|
Before Width: | Height: | Size: 691 B |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 539 B |
|
Before Width: | Height: | Size: 929 B |
@@ -1,194 +0,0 @@
|
||||
#include "kx_coeffs.h"
|
||||
#include "kx_protocol_x.h"
|
||||
|
||||
double X[KX_X_COUNT];
|
||||
PIVector<double> K;
|
||||
|
||||
|
||||
KX_Coefficients::KX_Coefficients(const PIString & config, const PIString & name, bool _pult) {
|
||||
setName("kx_coeffs");
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
fname = conf.getValue(name).getValue("file", "k.dat");
|
||||
readCoeffs();
|
||||
int ns = piMaxi(conf.getValue(name).getValue("count", 0), K.size_s());
|
||||
if (ns > K.size_s()) {
|
||||
K.resize(ns, 0.f);
|
||||
formulas.resize(ns);
|
||||
writeCoeffs();
|
||||
}
|
||||
config_ = config;
|
||||
name_ = name;
|
||||
pult_ = _pult;
|
||||
k_protocol = 0;
|
||||
renew();
|
||||
//readCoeffs();
|
||||
}
|
||||
|
||||
|
||||
KX_Coefficients::~KX_Coefficients() {
|
||||
stop();
|
||||
k_protocol->stop();
|
||||
delete k_protocol;
|
||||
}
|
||||
|
||||
|
||||
void KX_Coefficients::readCoeffs() {
|
||||
{
|
||||
PIConfig conf(fname, PIIODevice::ReadOnly);
|
||||
int cnt = conf.rootEntry().childCount();
|
||||
K.resize(cnt);
|
||||
formulas.resize(cnt);
|
||||
PIString kn, cf;
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
kn = "k" + PIString::fromNumber(i);
|
||||
K[i] = (double)conf.getValue(kn, 0.f);
|
||||
cf = conf.getValue(kn + ".formula", "");
|
||||
if (cf.isEmpty()) cf = PIString::fromNumber(K[i]);
|
||||
formulas[i] = cf;
|
||||
}
|
||||
}
|
||||
k_content = PIFile(fname, PIIODevice::ReadOnly).readAll();
|
||||
//piCout << k_content.size();
|
||||
piCoutObj << "Readed" << K.size_s() << "coefficients in" << k_content.size_s() << "bytes";
|
||||
coeffs_cnt = K.size_s();
|
||||
}
|
||||
|
||||
|
||||
void KX_Coefficients::writeCoeffs() {
|
||||
PIFile::remove(fname);
|
||||
PIFile conf(fname, PIIODevice::ReadWrite);
|
||||
//conf.clear();
|
||||
for (int i = 0; i < K.size_s(); i++) {
|
||||
conf << "k" + PIString::fromNumber(i) << " = " << PIString::fromNumber(K[i]).replaceAll(",", ".") << "\n";
|
||||
conf << "k" + PIString::fromNumber(i) << ".formula = " << formulas[i] << "\n";
|
||||
}
|
||||
//conf.close();
|
||||
//conf.writeAll();
|
||||
k_content = conf.readAll();
|
||||
//piCout << k_content.size();
|
||||
piCoutObj << "Written" << K.size_s() << "coefficients in" << k_content.size_s() << "bytes";
|
||||
coeffs_cnt = K.size_s();
|
||||
}
|
||||
|
||||
|
||||
void KX_Coefficients::setKFile(const PIString & f) {
|
||||
fname = f;
|
||||
readCoeffs();
|
||||
}
|
||||
|
||||
|
||||
void KX_Coefficients::sendCoeffs() {
|
||||
stop();
|
||||
int curcnt, pcnt = (k_content.size_s() - 1) / __BYTES_IN_PACKET + 1;
|
||||
k_protocol->to_k.full_count = k_content.size_s();
|
||||
for (int i = 0; i < pcnt; i++) {
|
||||
k_protocol->to_k.first_index = i * __BYTES_IN_PACKET;
|
||||
if (i == pcnt - 1) curcnt = k_content.size_s() % __BYTES_IN_PACKET;
|
||||
else curcnt = __BYTES_IN_PACKET;
|
||||
//cout << "send " << curcnt << " coeffs\n";
|
||||
k_protocol->to_k.count = curcnt;
|
||||
memcpy(k_protocol->to_k.coeffs, k_content.data(k_protocol->to_k.first_index), curcnt);
|
||||
//for (int j = 0; j < curcnt; j++) k_protocol->to_k.coeffs[j] = K.at(k_protocol->to_k.first_index + j);
|
||||
k_protocol->send();
|
||||
piMSleep(5);
|
||||
}
|
||||
//cout << "waiting for commit ...\n";
|
||||
waitingCommit = true;
|
||||
tm.reset();
|
||||
start(10);
|
||||
}
|
||||
|
||||
|
||||
void KX_Coefficients::receiveCoeffs() {
|
||||
stop();
|
||||
k_protocol->to_k.full_count = k_protocol->to_k.first_index = k_protocol->to_k.count = -6;
|
||||
k_protocol->send();
|
||||
//cout << "request send\n";
|
||||
//cout << "waiting for receive ...\n";
|
||||
waitingCommit = false;
|
||||
tm.reset();
|
||||
start(10);
|
||||
}
|
||||
|
||||
|
||||
void KX_Coefficients::received(bool correct) {
|
||||
//cout << "kpi received " << correct << endl;
|
||||
if (!correct) return;
|
||||
k_syns = k_protocol->from_k;
|
||||
if (waitingCommit) {
|
||||
if (k_syns.first_index != -1 ||
|
||||
k_syns.full_count != -1 ||
|
||||
k_syns.count != -k_content.size_s()) return;
|
||||
//cout << "commit received\n";
|
||||
waitingCommit = false;
|
||||
stop();
|
||||
//cout << "send succeed\n";
|
||||
//emit sendSucceed();
|
||||
sendSucceed();
|
||||
return;
|
||||
} else {
|
||||
if (k_syns.first_index == -6 && k_syns.full_count == -6 && k_syns.count == -6) {
|
||||
//cout << "request received\n";
|
||||
sendCoeffs();
|
||||
return;
|
||||
};
|
||||
}
|
||||
if (k_syns.first_index < 0 || k_syns.count < 0) return;
|
||||
if (k_syns.first_index == 0) {
|
||||
//cout << "first receive\n";
|
||||
k_tmp.resize(k_syns.full_count);
|
||||
received_cnt = 0;
|
||||
}
|
||||
//for (int i = 0; i < k_syns.count; i++) K.at(k_syns.first_index + i) = k_syns.coeffs[i];
|
||||
//piCout << k_tmp.size() << k_syns.first_index << k_syns.count;
|
||||
memcpy(k_tmp.data(k_syns.first_index), k_syns.coeffs, k_syns.count);
|
||||
received_cnt += k_syns.count;
|
||||
tm.reset();
|
||||
//cout << "received " << k_syns.count << " bytes with " << k_syns.first_index << " first\n";
|
||||
if (received_cnt < k_syns.full_count) return;
|
||||
//cout << "finally received " << received_cnt << " bytes\n";
|
||||
stop();
|
||||
PIFile::remove(fname);
|
||||
PIFile conf(fname, PIIODevice::ReadWrite);
|
||||
conf.write(k_tmp.data(), k_tmp.size_s());
|
||||
conf.close();
|
||||
readCoeffs();
|
||||
//writeCoeffs();
|
||||
k_protocol->to_k.full_count = k_protocol->to_k.first_index = -1;
|
||||
k_protocol->to_k.count = -received_cnt;
|
||||
k_protocol->send();
|
||||
waitingCommit = false;
|
||||
//emit receiveSucceed();
|
||||
receiveSucceed();
|
||||
//cout << "receive succeed\n";
|
||||
}
|
||||
|
||||
|
||||
void KX_Coefficients::renew() {
|
||||
if (k_protocol != 0) {
|
||||
k_protocol->stop();
|
||||
delete k_protocol;
|
||||
}
|
||||
k_protocol = new __KPi(config_, name_, pult_);
|
||||
CONNECT1(void, bool, k_protocol, received, this, received)
|
||||
waitingCommit = false;
|
||||
}
|
||||
|
||||
|
||||
void KX_Coefficients::tick(void * , int ) {
|
||||
//piCout << "timer" << tm.elapsed_s();
|
||||
if (tm.elapsed_s() < 10.) return;
|
||||
if (waitingCommit) {
|
||||
//cout << "commit timeout\n";
|
||||
//cout << "send failed\n";
|
||||
//emit sendFailed();
|
||||
sendFailed();
|
||||
} else {
|
||||
//cout << "receive timeout\n";
|
||||
//cout << "receive failed\n";
|
||||
//emit receiveFailed();
|
||||
receiveFailed();
|
||||
}
|
||||
waitingCommit = false;
|
||||
stop();
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
#ifndef KX_COEFFS_H
|
||||
#define KX_COEFFS_H
|
||||
|
||||
#include "piprotocol.h"
|
||||
|
||||
#define __BYTES_IN_PACKET 4000
|
||||
|
||||
extern PIVector<double> K;
|
||||
|
||||
class __KPi: public PIProtocol
|
||||
{
|
||||
PIOBJECT_SUBCLASS(__KPi, PIProtocol)
|
||||
public:
|
||||
#pragma pack (push, 1)
|
||||
struct KX_K_Sync {
|
||||
uchar type;
|
||||
uchar addr_to;
|
||||
int count;
|
||||
int full_count;
|
||||
int first_index;
|
||||
uchar coeffs[__BYTES_IN_PACKET];
|
||||
uint checksum;
|
||||
};
|
||||
#pragma pack (pop)
|
||||
__KPi(const PIString & config, const PIString & name, bool _pult = false): PIProtocol(config, name, &from_k, 2, &(from_k.count), sizeof(from_k) - 2, &to_k, sizeof(to_k)) {
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
PIConfig::Entry ce = conf.getValue(name);
|
||||
to_k.type = from_k.type = ce.getValue("type", 0xA);
|
||||
to_k.addr_to = ce.getValue("addr_k", 0x15);
|
||||
from_k.addr_to = ce.getValue("addr_pult", 0x75);
|
||||
if (_pult) piSwap<uchar>(to_k.addr_to, from_k.addr_to);
|
||||
packetExtractor()->setHeader(PIByteArray(&from_k, 2));
|
||||
start();
|
||||
}
|
||||
KX_K_Sync to_k, from_k;
|
||||
private:
|
||||
bool validate() {
|
||||
return (from_k.checksum == checksum_i(&from_k, sizeof(from_k) - 4));
|
||||
}
|
||||
bool aboutSend() {
|
||||
to_k.checksum = checksum_i(&to_k, sizeof(to_k) - 4);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class KX_Coefficients: public PITimer
|
||||
{
|
||||
PIOBJECT_SUBCLASS(KX_Coefficients, PITimer)
|
||||
friend class KX_Pult;
|
||||
public:
|
||||
KX_Coefficients(const PIString & config, const PIString & name = "k", bool _pult = false);
|
||||
~KX_Coefficients();
|
||||
|
||||
void readCoeffs();
|
||||
void writeCoeffs();
|
||||
|
||||
void sendCoeffs();
|
||||
void receiveCoeffs();
|
||||
|
||||
bool isReady() const {return !waitingCommit;}
|
||||
const PIString & fileName() const {return fname;}
|
||||
const PIString * fileName_ptr() const {return &fname;}
|
||||
int coeffsCount() {coeffs_cnt = K.size_s(); return coeffs_cnt;}
|
||||
const int * coeffsCount_ptr() const {return &coeffs_cnt;}
|
||||
|
||||
const PIString & formula(int index) const {return formulas[index];}
|
||||
void setFormula(int index, const PIString & f) {formulas[index] = f;}
|
||||
|
||||
void setKFile(const PIString & f);
|
||||
|
||||
EVENT(sendSucceed)
|
||||
EVENT(sendFailed)
|
||||
EVENT(receiveSucceed)
|
||||
EVENT(receiveFailed)
|
||||
|
||||
|
||||
__KPi * k_protocol;
|
||||
|
||||
private:
|
||||
EVENT_HANDLER1(void, received, bool, correct);
|
||||
void renew();
|
||||
void tick(void *, int);
|
||||
|
||||
__KPi::KX_K_Sync k_syns;
|
||||
bool pult_, waitingCommit;
|
||||
int received_cnt, coeffs_cnt;
|
||||
PIString fname, config_, name_;
|
||||
PIStringList formulas;
|
||||
PIByteArray k_content, k_tmp;
|
||||
PITimeMeasurer tm;
|
||||
|
||||
};
|
||||
|
||||
#endif // KX_COEFFS_H
|
||||
@@ -1,126 +0,0 @@
|
||||
#ifndef KX_PROTOCOL_C_H
|
||||
#define KX_PROTOCOL_C_H
|
||||
|
||||
#include "piprotocol.h"
|
||||
|
||||
|
||||
#pragma pack (push, 1)
|
||||
|
||||
|
||||
struct KX_C_Header {
|
||||
uchar type;
|
||||
uchar addr_to;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct KX_C_Command: KX_C_Header {
|
||||
KX_C_Command() {command = -1;}
|
||||
int command;
|
||||
uint checksum;
|
||||
};
|
||||
|
||||
|
||||
struct KX_C_Event: KX_C_Header {
|
||||
KX_C_Event() {event = -1;}
|
||||
PISystemTime time;
|
||||
int event;
|
||||
uint checksum;
|
||||
};
|
||||
|
||||
|
||||
#pragma pack (pop)
|
||||
|
||||
|
||||
// Client side
|
||||
|
||||
class KX_Protocol_C: public PIProtocol
|
||||
{
|
||||
PIOBJECT_SUBCLASS(KX_Protocol_C, PIProtocol)
|
||||
public:
|
||||
KX_Protocol_C(const PIString & config, const PIString & name = "c"): PIProtocol(config, name, &from_buff, 2, &(from_buff.command), sizeof(from_buff) - 2, &to_pult, sizeof(to_pult)) {
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
PIConfig::Entry ce = conf.getValue(name);
|
||||
to_pult.type = from_buff.type = ce.getValue("type", 0xC);
|
||||
to_pult.addr_to = ce.getValue("addr_pult", 0x15);
|
||||
from_buff.addr_to = ce.getValue("addr_c", 0x75);
|
||||
from_pult = from_buff;
|
||||
packetExtractor()->setSplitMode(PIPacketExtractor::Header);
|
||||
packetExtractor()->setHeader(PIByteArray(&from_buff, 2));
|
||||
startReceive();
|
||||
}
|
||||
|
||||
void sendEvent(int ev) {
|
||||
to_pult.time = PISystemTime::current();
|
||||
to_pult.event = ev;
|
||||
send();
|
||||
}
|
||||
EVENT1(commandReceived, int, command)
|
||||
|
||||
KX_C_Command from_pult;
|
||||
KX_C_Event to_pult;
|
||||
|
||||
private:
|
||||
bool validate() {
|
||||
if (checksum_i(&from_buff, sizeof(from_buff) - 4) != from_buff.checksum) return false;
|
||||
from_pult = from_buff;
|
||||
commandReceived(from_pult.command);
|
||||
return true;
|
||||
}
|
||||
bool aboutSend() {
|
||||
to_pult.checksum = checksum_i(&to_pult, sizeof(to_pult) - 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
KX_C_Command from_buff;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Pult side
|
||||
|
||||
class __KX_Protocol_C: public PIProtocol
|
||||
{
|
||||
PIOBJECT_SUBCLASS(__KX_Protocol_C, PIProtocol)
|
||||
public:
|
||||
__KX_Protocol_C(const PIString & config, const PIString & name): PIProtocol(config, name, &from_buff, 2, &(from_buff.time), sizeof(from_buff) - 2, &to_c, sizeof(to_c)) {
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
PIConfig::Entry ce = conf.getValue(name);
|
||||
to_c.type = from_buff.type = ce.getValue("type", 0xC);
|
||||
to_c.addr_to = ce.getValue("addr_c", 0x75);
|
||||
from_buff.addr_to = ce.getValue("addr_pult", 0x15);
|
||||
from_c = from_buff;
|
||||
packetExtractor()->setSplitMode(PIPacketExtractor::Header);
|
||||
packetExtractor()->setHeader(PIByteArray(&from_buff, 2));
|
||||
startReceive();
|
||||
}
|
||||
|
||||
void sendCommand(int cmd) {
|
||||
to_c.command = cmd;
|
||||
send();
|
||||
}
|
||||
EVENT2(eventReceived, int, event, PISystemTime, time)
|
||||
|
||||
KX_C_Event from_c;
|
||||
KX_C_Command to_c;
|
||||
|
||||
private:
|
||||
bool validate() {
|
||||
if (checksum_i(&from_buff, sizeof(from_buff) - 4) != from_buff.checksum) return false;
|
||||
from_c = from_buff;
|
||||
eventReceived(from_c.event, from_c.time);
|
||||
return true;
|
||||
}
|
||||
bool aboutSend() {
|
||||
//piCout << "send command" << to_c.command;
|
||||
to_c.checksum = checksum_i(&to_c, sizeof(to_c) - 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
KX_C_Event from_buff;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // KX_PROTOCOL_C_H
|
||||
@@ -1,121 +0,0 @@
|
||||
#ifndef KX_PROTOCOL_X_H
|
||||
#define KX_PROTOCOL_X_H
|
||||
|
||||
#include "piprotocol.h"
|
||||
|
||||
#define KX_X_PACKET_NUM 20
|
||||
#define KX_X_COUNT 16384
|
||||
|
||||
extern double X[KX_X_COUNT];
|
||||
|
||||
|
||||
#pragma pack (push, 1)
|
||||
|
||||
|
||||
struct KX_X_Header {
|
||||
uchar type;
|
||||
uchar addr_to;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct KX_X_Numbers: KX_X_Header {
|
||||
int x_num[KX_X_PACKET_NUM];
|
||||
uint checksum;
|
||||
};
|
||||
|
||||
|
||||
struct KX_X_Data: KX_X_Header {
|
||||
int x_num[KX_X_PACKET_NUM];
|
||||
double x_data[KX_X_PACKET_NUM];
|
||||
uint checksum;
|
||||
};
|
||||
|
||||
|
||||
#pragma pack (pop)
|
||||
|
||||
|
||||
// Client side
|
||||
|
||||
class KX_Protocol_X: public PIProtocol
|
||||
{
|
||||
PIOBJECT_SUBCLASS(KX_Protocol_X, PIProtocol)
|
||||
public:
|
||||
KX_Protocol_X(const PIString & config, const PIString & name = "x"): PIProtocol(config, name, &from_buff, 2, &(from_buff.x_num[0]), sizeof(from_buff) - 2, &to_pult, sizeof(to_pult)) {
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
PIConfig::Entry ce = conf.getValue(name);
|
||||
to_pult.type = from_buff.type = ce.getValue("type", 0xB);
|
||||
to_pult.addr_to = ce.getValue("addr_pult", 0x15);
|
||||
from_buff.addr_to = ce.getValue("addr_x", 0x75);
|
||||
from_pult = from_buff;
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
|
||||
to_pult.x_num[i] = from_pult.x_num[i] = -1;
|
||||
packetExtractor()->setSplitMode(PIPacketExtractor::Header);
|
||||
packetExtractor()->setHeader(PIByteArray(&from_buff, 2));
|
||||
start();
|
||||
}
|
||||
|
||||
KX_X_Numbers from_pult;
|
||||
KX_X_Data to_pult;
|
||||
|
||||
private:
|
||||
bool validate() {
|
||||
if (checksum_i(&from_buff, sizeof(from_buff) - 4) != from_buff.checksum) return false;
|
||||
from_pult = from_buff;
|
||||
return true;
|
||||
}
|
||||
bool aboutSend() {
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
|
||||
to_pult.x_num[i] = from_pult.x_num[i];
|
||||
to_pult.x_data[i] = from_pult.x_num[i] < 0 ? 0. : X[from_pult.x_num[i]];
|
||||
}
|
||||
to_pult.checksum = checksum_i(&to_pult, sizeof(to_pult) - 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
KX_X_Numbers from_buff;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Pult side
|
||||
|
||||
class __KX_Protocol_X: public PIProtocol
|
||||
{
|
||||
PIOBJECT_SUBCLASS(__KX_Protocol_X, PIProtocol)
|
||||
public:
|
||||
__KX_Protocol_X(const PIString & config, const PIString & name): PIProtocol(config, name, &from_buff, 2, &(from_buff.x_num[0]), sizeof(from_buff) - 2, &to_x, sizeof(to_x)) {
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
PIConfig::Entry ce = conf.getValue(name);
|
||||
to_x.type = from_buff.type = ce.getValue("type", 0xB);
|
||||
to_x.addr_to = ce.getValue("addr_x", 0x75);
|
||||
from_buff.addr_to = ce.getValue("addr_pult", 0x15);
|
||||
from_x = from_buff;
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
|
||||
to_x.x_num[i] = -1;
|
||||
packetExtractor()->setSplitMode(PIPacketExtractor::Header);
|
||||
packetExtractor()->setHeader(PIByteArray(&from_buff, 2));
|
||||
start();
|
||||
}
|
||||
|
||||
KX_X_Data from_x;
|
||||
KX_X_Numbers to_x;
|
||||
|
||||
private:
|
||||
bool validate() {
|
||||
if (checksum_i(&from_buff, sizeof(from_buff) - 4) != from_buff.checksum) return false;
|
||||
from_x = from_buff;
|
||||
return true;
|
||||
}
|
||||
bool aboutSend() {
|
||||
to_x.checksum = checksum_i(&to_x, sizeof(to_x) - 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
KX_X_Data from_buff;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // KX_PROTOCOL_X_H
|
||||
@@ -1,848 +0,0 @@
|
||||
#include <QScrollBar>
|
||||
#include <QMessageBox>
|
||||
#include <math.h>
|
||||
#include "kx_pult.h"
|
||||
#include "ui_kx_pult.h"
|
||||
#include "piqt.h"
|
||||
#include "qpiconfig.h"
|
||||
|
||||
|
||||
bool isNormalDouble(const double & v) {
|
||||
#ifdef WINDOWS
|
||||
return true;
|
||||
#else
|
||||
return !isnan(v) && !isinf(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
XCheck::XCheck(int index): QWidget() {
|
||||
index_ = index;
|
||||
setProperty("index", index);
|
||||
setMouseTracking(true);
|
||||
check.setText(QString::number(index + 1) + " ");
|
||||
check.setAutoFillBackground(true);
|
||||
spin.setMaximum(KX_X_COUNT - 1);
|
||||
QBoxLayout * l = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
l->setMargin(0);
|
||||
l->setSpacing(2);
|
||||
l->addWidget(&check);
|
||||
l->addWidget(&spin);
|
||||
setLayout(l);
|
||||
//check.installEventFilter(this);
|
||||
//spin.installEventFilter(this);
|
||||
connect(&spin, SIGNAL(valueChanged(int)), this, SLOT(spinChanged(int)));
|
||||
connect(&check, SIGNAL(toggled(bool)), this, SLOT(checkChanged_(bool)));
|
||||
}
|
||||
|
||||
|
||||
bool XCheck::eventFilter(QObject * o, QEvent * e) {
|
||||
if (e->type() == QEvent::Enter)
|
||||
qApp->postEvent(this, new QEvent(e->type()));
|
||||
return QWidget::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
KX_Pult::KX_Pult(): QMainWindow(), config_("kx_pult.conf"), name_x("x"), name_c("c"),
|
||||
config(piqt(config_), QIODevice::ReadWrite), coeffs(config_, "k", true) {
|
||||
//cout << sizeof(coeffsK.k_protocol->to_k) << endl;
|
||||
ui = new Ui::KX_Pult();
|
||||
ui->setupUi(this);
|
||||
ui->configWidget->setQPIConfig(&config);
|
||||
ui->configWidget->expandAll();
|
||||
ui->list->viewport()->installEventFilter(this);
|
||||
ui->treeK->viewport()->installEventFilter(this);
|
||||
ui->scrollArea->setAutoFillBackground(false);
|
||||
ui->scrollAreaWidgetContents->setAutoFillBackground(false);
|
||||
ui->widget->setAutoFillBackground(false);
|
||||
ui->label_17->setFixedSize(preferredIconSize(1.25, this));
|
||||
log_menu.addAction(ui->actionClear);
|
||||
prot_x = 0;
|
||||
prot_c = 0;
|
||||
show_x = config.getValue("show_x", true);
|
||||
if (!show_x)
|
||||
ui->tabWidget->removeTab(1);
|
||||
session.setFile("session_KX_Pult.conf");
|
||||
session.addEntry(this);
|
||||
session.addEntry(ui->tabWidget);
|
||||
session.addEntry(ui->checkKHideEmpty);
|
||||
session.addEntry(ui->checkKHideNormal);
|
||||
session.addEntry(ui->checkKHideExpressions);
|
||||
session.addEntry(ui->checkKAutoCalculate);
|
||||
needWrite = isPause = false;
|
||||
timer = 0;
|
||||
//x.resize(KX_X_PACKET_NUM);
|
||||
//k.resize(K_NUM);
|
||||
QPalette pal = palette();
|
||||
QColor col;
|
||||
ui->graphic->setGraphicsCount(0);
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
|
||||
XCheck * xc = new XCheck(i);
|
||||
xc->installEventFilter(this);
|
||||
connect(xc, SIGNAL(valueChanged(int, int)), this, SLOT(changedX(int,int)));
|
||||
connect(xc, SIGNAL(checkChanged(int, bool)), this, SLOT(toggledX(int, bool)));
|
||||
col = QColor::fromHsv(360 / KX_X_PACKET_NUM * i, 255, 200);
|
||||
pal.setColor(QPalette::Button, col);
|
||||
pal.setColor(QPalette::Window, col);
|
||||
pal.setColor(QPalette::WindowText, invertColor(col));
|
||||
xc->check.setPalette(pal);
|
||||
ui->graphic->addGraphic(QString::number(i), col);
|
||||
ui->graphic->setGraphicVisible(false, i);
|
||||
checks << xc;
|
||||
((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(xc, (i / 10) * 2, i % 10);
|
||||
QLabel * lbl = new QLabel("0"); lbl->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
|
||||
values << lbl;
|
||||
((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(lbl, (i / 10) * 2 + 1, i % 10);
|
||||
//xc->show();
|
||||
}
|
||||
renew();
|
||||
icon_record = QIcon(":/icons/media-record.png");
|
||||
icon_stop = QIcon(":/icons/media-playback-stop.png");
|
||||
outdir = dir.absolutePath();
|
||||
if (!dir.exists()) dir.mkdir(outdir);
|
||||
outdir += "/";
|
||||
ui->treeK->setColumnWidth(0, 60);
|
||||
ui->treeK->setColumnWidth(1, 250);
|
||||
ui->treeK->setColumnWidth(3, 100);
|
||||
ui->treeK->setColumnWidth(4, 100);
|
||||
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
|
||||
ui->spinSize->setValue(K.size_s());
|
||||
addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
|
||||
CONNECT(void, &coeffs, sendFailed, this, pip_sendFailed);
|
||||
CONNECT(void, &coeffs, sendSucceed, this, pip_sendSucceed);
|
||||
CONNECT(void, &coeffs, receiveFailed, this, pip_receiveFailed);
|
||||
CONNECT(void, &coeffs, receiveSucceed, this, pip_receiveSucceed);
|
||||
connect(this, SIGNAL(q_k_sendFailed()), this, SLOT(k_sendFailed()), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(q_k_sendSucceed()), this, SLOT(k_sendSucceed()), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(q_k_receiveFailed()), this, SLOT(k_receiveFailed()), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(q_k_receiveSucceed()), this, SLOT(k_receiveSucceed()), Qt::QueuedConnection);
|
||||
connect(&timer_diag, SIGNAL(timeout()), this, SLOT(updateDiag()));
|
||||
connect(&session, SIGNAL(loading(QPIConfig&)), this, SLOT(loading(QPIConfig&)));
|
||||
connect(&session, SIGNAL(saving(QPIConfig&)), this, SLOT(saving(QPIConfig&)));
|
||||
connect(ui->checkKHideEmpty, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
|
||||
connect(ui->checkKHideNormal, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
|
||||
connect(ui->checkKHideExpressions, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
|
||||
connect(ui->lineKSearch, SIGNAL(textChanged(QString)), this, SLOT(filterTree()));
|
||||
session.load();
|
||||
updateKDesc();
|
||||
updateCDesc();
|
||||
timer_diag.start(40);
|
||||
timer_update = startTimer(25);
|
||||
}
|
||||
|
||||
|
||||
KX_Pult::~KX_Pult() {
|
||||
session.save();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::loading(QPIConfig & conf) {
|
||||
kdesc_file = conf.getValue("kdesc_file").stringValue();
|
||||
cdesc_file = conf.getValue("cdesc_file").stringValue();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::saving(QPIConfig & conf) {
|
||||
conf.setValue("kdesc_file", kdesc_file);
|
||||
conf.setValue("cdesc_file", cdesc_file);
|
||||
}
|
||||
|
||||
|
||||
bool KX_Pult::eventFilter(QObject * o, QEvent * e) {
|
||||
if (o == ui->list->viewport()) {
|
||||
if (e->type() == QEvent::ContextMenu) {
|
||||
clear_target = 0;
|
||||
log_menu.popup(((QContextMenuEvent*)e)->globalPos());
|
||||
}
|
||||
return QMainWindow::eventFilter(o, e);
|
||||
}
|
||||
if (o == ui->treeK->viewport()) {
|
||||
if (e->type() == QEvent::ContextMenu) {
|
||||
clear_target = 1;
|
||||
log_menu.popup(((QContextMenuEvent*)e)->globalPos());
|
||||
}
|
||||
return QMainWindow::eventFilter(o, e);
|
||||
}
|
||||
int ind = o->property("index").toInt();
|
||||
//qDebug() << "event" << i << e->type();
|
||||
switch (e->type()) {
|
||||
case QEvent::Enter:
|
||||
ui->graphic->setAutoUpdate(false);
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
|
||||
ui->graphic->setGraphicLineWidth(ind == i ? 3. : 1., i);
|
||||
ui->graphic->setAutoUpdate(true);
|
||||
ui->graphic->update();
|
||||
break;
|
||||
case QEvent::Leave:
|
||||
ui->graphic->setAutoUpdate(false);
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
|
||||
ui->graphic->setGraphicLineWidth(1., i);
|
||||
ui->graphic->setAutoUpdate(true);
|
||||
ui->graphic->update();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return QMainWindow::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::timerEvent(QTimerEvent * e) {
|
||||
if (e->timerId() == timer_update) {
|
||||
if (need_update) {
|
||||
need_update = false;
|
||||
ui->graphic->updateGraphics();
|
||||
}
|
||||
}
|
||||
if (e->timerId() == timer) {
|
||||
static QString sPI = QString::number(atan(1) * 4., 'f', 14).leftJustified(14);
|
||||
static int cnt = 0;
|
||||
int si = qMax<int>(cnt - 6, 0);
|
||||
++cnt;
|
||||
cnt %= 23;
|
||||
ui->labelWait->setText(QString(si, QChar(' ')) + sPI.mid(cnt - 6, 6).trimmed());
|
||||
if (!coeffs.isReady()) return;
|
||||
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
|
||||
//ui->table->showK();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::setControlsEnable(bool enable) {
|
||||
foreach (XCheck * i, checks)
|
||||
i->setEnabled(enable);
|
||||
ui->buttonShowAll->setEnabled(enable);
|
||||
ui->buttonHideAll->setEnabled(enable);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::setX(const KX_X_Data & data) {
|
||||
if (!show_x) return;
|
||||
//ui->graphic->lock();
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
|
||||
if (!isNormalDouble(data.x_data[i])) continue;
|
||||
ui->graphic->addPoint(data.x_data[i], i, false);
|
||||
values[i]->setText(QString("(%1): %2").arg(data.x_num[i]).arg(data.x_data[i]));
|
||||
}
|
||||
//ui->graphic->unlock();
|
||||
if (!isPause) {
|
||||
need_update = true;
|
||||
}
|
||||
if (!needWrite) return;
|
||||
stream << QString::number(tm.elapsed() / 1000., 'f', 3) << " " << QTime::currentTime().toString("hh:mm:ss") << " " << wcnt++;
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
|
||||
stream << " " << QString::number(data.x_data[i], 'f', 4);
|
||||
stream << "\n";
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::addToList(const QString & s, const QColor & c) {
|
||||
ui->list->addItem(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:ss - ") + s);
|
||||
ui->list->item(ui->list->count() - 1)->setTextColor(c);
|
||||
ui->list->scrollToBottom();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonRecord_clicked() {
|
||||
static bool isRec = false;
|
||||
int cinc = 0;
|
||||
QString str;
|
||||
isRec = !isRec;
|
||||
setControlsEnable(!isRec);
|
||||
if (isRec) {
|
||||
tm.restart();
|
||||
file.close();
|
||||
file.setFileName(outdir + getNewFileName(cinc));
|
||||
while (file.exists())
|
||||
file.setFileName(outdir + getNewFileName(cinc++));
|
||||
file.open(QIODevice::ReadWrite);
|
||||
stream.setDevice(&file);
|
||||
stream << "T V C";
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
|
||||
stream << " X" + QString::number(checks[i]->spin.value());
|
||||
stream << "\n";
|
||||
wcnt = 0;
|
||||
needWrite = true;
|
||||
ui->buttonRecord->setText(trUtf8("Finish record"));
|
||||
ui->buttonRecord->setIcon(icon_stop);
|
||||
emit recordStarted(QFileInfo(file).completeBaseName());
|
||||
} else {
|
||||
needWrite = false;
|
||||
stream.setDevice(0);
|
||||
file.close();
|
||||
ui->buttonRecord->setText(trUtf8("Start record"));
|
||||
ui->buttonRecord->setIcon(icon_record);
|
||||
emit recordStopped(QFileInfo(file).completeBaseName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_actionClear_triggered() {
|
||||
switch (clear_target) {
|
||||
case 0:
|
||||
ui->list->clear();
|
||||
break;
|
||||
case 1:
|
||||
clearSelected();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::clearSelected() {
|
||||
QList<QTreeWidgetItem * > si = ui->treeK->selectedItems();
|
||||
ui->treeK->setUpdatesEnabled(false);
|
||||
ui->treeK->blockSignals(true);
|
||||
foreach (QTreeWidgetItem * i, si) {
|
||||
int ki = i->text(0).toInt();
|
||||
i->setText(2, "");
|
||||
coeffs.setFormula(ki, "");
|
||||
}
|
||||
ui->treeK->blockSignals(false);
|
||||
ui->treeK->setUpdatesEnabled(true);
|
||||
if (ui->checkKAutoCalculate->isChecked()) {
|
||||
QApplication::processEvents();
|
||||
calculate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString KX_Pult::typeName(const QString & n) const {
|
||||
if (n.isEmpty()) return "";
|
||||
switch (n[0].toLatin1()) {
|
||||
case 'l': return trUtf8("list"); break;
|
||||
case 'b': return trUtf8("bool"); break;
|
||||
case 'n': return trUtf8("int"); break;
|
||||
case 'f': return trUtf8("double"); break;
|
||||
case 'c': return trUtf8("color"); break;
|
||||
case 'r': return trUtf8("rect"); break;
|
||||
case 'a': return trUtf8("rect"); break;
|
||||
case 'p': return trUtf8("point"); break;
|
||||
case 'v': return trUtf8("vector"); break;
|
||||
case 'i': return trUtf8("IP"); break;
|
||||
case 'e': return trUtf8("enum"); break;
|
||||
case 'F': return trUtf8("file"); break;
|
||||
case 'D': return trUtf8("dir"); break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::received(bool ok) {
|
||||
if (!ok) return;
|
||||
setX(prot_x->from_x);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_treeK_itemClicked(QTreeWidgetItem * item, int column) {
|
||||
Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
if (column == 2) f |= Qt::ItemIsEditable;
|
||||
item->setFlags(f);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_treeK_itemChanged(QTreeWidgetItem * item, int column) {
|
||||
if (column != 2) return;
|
||||
int ki = item->text(0).toInt();
|
||||
coeffs.setFormula(ki, piqt(item->text(column)));
|
||||
if (ui->checkKAutoCalculate->isChecked())
|
||||
calculate();
|
||||
}
|
||||
|
||||
|
||||
QString KX_Pult::getNewFileName(int inc) {
|
||||
dir.refresh();
|
||||
dir.setNameFilters(QStringList("Experiment_*.txt"));
|
||||
return "Experiment_" + QDateTime::currentDateTime().toString("dd_MM_yy__hh_mm_ss") + "__" +
|
||||
QString::number(dir.entryList().count() + inc) + ".txt";
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonSendK_clicked() {
|
||||
on_buttonWrite_clicked();
|
||||
coeffs.sendCoeffs();
|
||||
if (timer != 0) killTimer(timer);
|
||||
timer = startTimer(100);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonReceiveK_clicked() {
|
||||
coeffs.receiveCoeffs();
|
||||
if (timer != 0) killTimer(timer);
|
||||
timer = startTimer(100);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonShowAll_clicked() {
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
|
||||
checks[i]->check.setChecked(true);
|
||||
//ui->graphic->setGraphicVisible(true, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonHideAll_clicked() {
|
||||
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
|
||||
checks[i]->check.setChecked(false);
|
||||
//ui->graphic->setGraphicVisible(false, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonRead_clicked() {
|
||||
coeffs.readCoeffs();
|
||||
addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
|
||||
updateTree();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonWrite_clicked() {
|
||||
coeffs.writeCoeffs();
|
||||
addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonResize_clicked() {
|
||||
K.resize(ui->spinSize->value());
|
||||
coeffs.formulas.resize(ui->spinSize->value());
|
||||
ui->spinSize->setStyleSheet("");
|
||||
updateTree();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonSetKDesc_clicked() {
|
||||
QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with K description"), kdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)");
|
||||
if (ret.isEmpty()) return;
|
||||
kdesc_file = QDir::current().relativeFilePath(ret);
|
||||
updateKDesc(true);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_buttonSetCDesc_clicked() {
|
||||
QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with C description"), cdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)");
|
||||
if (ret.isEmpty()) return;
|
||||
cdesc_file = QDir::current().relativeFilePath(ret);
|
||||
updateCDesc();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_spinSize_valueChanged(int) {
|
||||
ui->spinSize->setStyleSheet("");
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::k_sendFailed() {
|
||||
stopWait();
|
||||
addToList(trUtf8("K not sended"), Qt::darkRed);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::k_sendSucceed() {
|
||||
stopWait();
|
||||
addToList(trUtf8("K sended"), Qt::darkGreen);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::k_receiveFailed() {
|
||||
stopWait();
|
||||
addToList(trUtf8("K not received"), Qt::darkRed);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::k_receiveSucceed() {
|
||||
stopWait();
|
||||
addToList(trUtf8("K received"), Qt::darkGreen);
|
||||
addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
|
||||
ui->spinSize->setValue(K.size_s());
|
||||
updateTree();
|
||||
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::on_spinBuffer_editingFinished() {
|
||||
ui->graphic->setHistorySize(ui->spinBuffer->value());
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::stopWait() {
|
||||
killTimer(timer);
|
||||
timer = 0;
|
||||
ui->labelWait->setText(" ");
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::updateGraph() {
|
||||
ui->graphic->updateGraphics();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::updateDiag() {
|
||||
ui->labelKReceiver->setText(piqt(coeffs.k_protocol->receiverDeviceName() + " - " + coeffs.k_protocol->receiverDeviceState()));
|
||||
ui->labelKSender->setText(piqt(coeffs.k_protocol->senderDeviceName()));
|
||||
ui->spinKSended->setValue(coeffs.k_protocol->sendCount());
|
||||
ui->spinKReceived->setValue(coeffs.k_protocol->receiveCount());
|
||||
ui->spinKWrong->setValue(coeffs.k_protocol->wrongCount());
|
||||
ui->spinKMissed->setValue(coeffs.k_protocol->missedCount());
|
||||
ui->labelKType->setText("0x" + QString::number(coeffs.k_protocol->from_k.type, 16).toUpper().rightJustified(2, '0'));
|
||||
ui->labelKAddrPult->setText("0x" + QString::number(coeffs.k_protocol->from_k.addr_to, 16).toUpper().rightJustified(2, '0'));
|
||||
ui->labelKAddr->setText("0x" + QString::number(coeffs.k_protocol->to_k.addr_to, 16).toUpper().rightJustified(2, '0'));
|
||||
|
||||
ui->labelXReceiver->setText(piqt(prot_x->receiverDeviceName() + " - " + prot_x->receiverDeviceState()));
|
||||
ui->labelXSender->setText(piqt(prot_x->senderDeviceName()));
|
||||
ui->spinXSended->setValue(prot_x->sendCount());
|
||||
ui->spinXReceived->setValue(prot_x->receiveCount());
|
||||
ui->spinXWrong->setValue(prot_x->wrongCount());
|
||||
ui->spinXMissed->setValue(prot_x->missedCount());
|
||||
ui->labelXType->setText("0x" + QString::number(prot_x->from_x.type, 16).toUpper().rightJustified(2, '0'));
|
||||
ui->labelXAddrPult->setText("0x" + QString::number(prot_x->from_x.addr_to, 16).toUpper().rightJustified(2, '0'));
|
||||
ui->labelXAddr->setText("0x" + QString::number(prot_x->to_x.addr_to, 16).toUpper().rightJustified(2, '0'));
|
||||
|
||||
ui->labelCReceiver->setText(piqt(prot_c->receiverDeviceName() + " - " + prot_c->receiverDeviceState()));
|
||||
ui->labelCSender->setText(piqt(prot_c->senderDeviceName()));
|
||||
ui->spinCSended->setValue(prot_c->sendCount());
|
||||
ui->spinCReceived->setValue(prot_c->receiveCount());
|
||||
ui->spinCWrong->setValue(prot_c->wrongCount());
|
||||
ui->spinCMissed->setValue(prot_c->missedCount());
|
||||
ui->labelCType->setText("0x" + QString::number(prot_c->from_c.type, 16).toUpper().rightJustified(2, '0'));
|
||||
ui->labelCAddrPult->setText("0x" + QString::number(prot_c->from_c.addr_to, 16).toUpper().rightJustified(2, '0'));
|
||||
ui->labelCAddr->setText("0x" + QString::number(prot_c->to_c.addr_to, 16).toUpper().rightJustified(2, '0'));
|
||||
}
|
||||
|
||||
|
||||
int KX_Pult::parseHeader(const QString & file, QMap<int, KX_Pult::KDesc> & map) {
|
||||
map.clear();
|
||||
QFile f(file);
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
updateTree();
|
||||
addToList(trUtf8("Update descriptions from \"%1\": error").arg(file), Qt::darkRed);
|
||||
return 0;
|
||||
}
|
||||
addToList(trUtf8("Update descriptions from \"%1\"").arg(file), Qt::darkMagenta);
|
||||
QTextStream s(&f);
|
||||
int cind = -1;
|
||||
bool found = false;
|
||||
//qDebug() << "\nparse" << file;
|
||||
while (!s.atEnd()) {
|
||||
QString line = s.readLine().trimmed(), num, name, type, comment;
|
||||
int i = line.indexOf("//");
|
||||
if (i >= 0) {
|
||||
comment = line.right(line.length() - i - 2);
|
||||
type = comment.left(1);
|
||||
comment = comment.right(comment.length() - 1).trimmed();
|
||||
line = line.left(i).trimmed();
|
||||
}
|
||||
if (line.isEmpty()) continue;
|
||||
if (line.contains("enum")) {
|
||||
found = true;
|
||||
continue;
|
||||
}
|
||||
if (!found) continue;
|
||||
if (line.contains('}'))
|
||||
break;
|
||||
line.remove(',').remove(' ').remove('\t');
|
||||
i = line.indexOf("=");
|
||||
if (i >= 0) {
|
||||
num = line.right(line.length() - i - 1).trimmed();
|
||||
line = line.left(i).trimmed();
|
||||
}
|
||||
name = line;
|
||||
if (num.isEmpty())
|
||||
++cind;
|
||||
else
|
||||
cind = Q2PIString(num).toInt();
|
||||
KDesc kd;
|
||||
kd.index = cind;
|
||||
kd.name = name;
|
||||
kd.type = type;
|
||||
kd.comment = comment;
|
||||
map[kd.index] = kd;
|
||||
//qDebug() << name << cind << type << comment;
|
||||
}
|
||||
cind++;
|
||||
return cind;
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::updateKDesc(bool ask_move) {
|
||||
int cind = parseHeader(kdesc_file, kdesc);
|
||||
if (K.size_s() < cind) {
|
||||
ui->spinSize->setValue(cind);
|
||||
ui->spinSize->setStyleSheet("background-color: rgb(220, 220, 255);");
|
||||
}
|
||||
bool move = false;
|
||||
if (ask_move)
|
||||
move = (QMessageBox::question(this, "KX Pult", "Save values at associated names?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes);
|
||||
updateTree(move);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::updateCDesc() {
|
||||
parseHeader(cdesc_file, cdesc);
|
||||
updateCommands();
|
||||
}
|
||||
|
||||
|
||||
bool stringComp(const QString & s1, const QString & s2) {
|
||||
if (s1.size() != s2.size())
|
||||
return s1.size() > s2.size();
|
||||
return s1 > s2;
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::updateTree(bool move) {
|
||||
int sp = ui->treeK->verticalScrollBar()->value();
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
//qDebug() << "fill tree ...";
|
||||
QMap<QString, QString> prev_val;
|
||||
if (move) {
|
||||
for (int i = 0; i < ui->treeK->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
|
||||
if (!ti->text(1).isEmpty())
|
||||
prev_val[ti->text(1)] = ti->text(2);
|
||||
}
|
||||
}
|
||||
ui->treeK->clear();
|
||||
ui->treeK->setUpdatesEnabled(false);
|
||||
eval.clearCustomVariables();
|
||||
for (int i = 0; i < K.size_s(); ++i) {
|
||||
QTreeWidgetItem * ti = new QTreeWidgetItem();
|
||||
KDesc kd = kdesc[i];
|
||||
QString kn = QString("k%1").arg(i);
|
||||
knames[kn] = i;
|
||||
knames_sort << kn;
|
||||
if (eval.content.findVariable(kn) < 0)
|
||||
eval.content.addVariable(kn, 0., false);
|
||||
if (!kd.name.isEmpty()) {
|
||||
knames[kd.name] = i;
|
||||
knames_sort << kd.name;
|
||||
eval.content.addVariable(kd.name, 0., false);
|
||||
}
|
||||
if (move && !kd.name.isEmpty()) {
|
||||
if (prev_val.contains(kd.name))
|
||||
coeffs.setFormula(i, Q2PIString(prev_val[kd.name]));
|
||||
}
|
||||
ti->setText(0, QString::number(i));
|
||||
ti->setText(1, kd.name);
|
||||
ti->setText(2, PI2QString(coeffs.formula(i)));
|
||||
ti->setText(3, QString::number(K[i]));
|
||||
ti->setText(4, typeName(kd.type));
|
||||
ti->setText(5, kd.comment);
|
||||
ui->treeK->addTopLevelItem(ti);
|
||||
}
|
||||
eval.content.sortVariables();
|
||||
//qDebug() << "fill tree ok";
|
||||
//qDebug() << "sort ...";
|
||||
qSort(knames_sort.begin(), knames_sort.end(), stringComp);
|
||||
//qDebug() << "names" << knames_sort;
|
||||
//qDebug() << "sort ok";
|
||||
QApplication::restoreOverrideCursor();
|
||||
ui->treeK->setUpdatesEnabled(true);
|
||||
ui->treeK->verticalScrollBar()->setValue(sp);
|
||||
calculate();
|
||||
filterTree();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::updateCommands() {
|
||||
while (ui->layoutCommands->count() > 0)
|
||||
delete ui->layoutCommands->itemAt(0)->widget();
|
||||
QMapIterator<int, KDesc> it(cdesc);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
KDesc kd = it.value();
|
||||
QPushButton * b = new QPushButton();
|
||||
QString text = kd.name;
|
||||
if (!kd.comment.isEmpty())
|
||||
text += QString("\n(%1)").arg(kd.comment);
|
||||
b->setText(text);
|
||||
b->setProperty("_command", kd.index);
|
||||
connect(b, SIGNAL(clicked()), this, SLOT(commandClicked()));
|
||||
ui->layoutCommands->addWidget(b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::filterTree() {
|
||||
bool he = ui->checkKHideEmpty->isChecked();
|
||||
bool hn = ui->checkKHideNormal->isChecked();
|
||||
bool hs = ui->checkKHideExpressions->isChecked();
|
||||
bool ok = false;
|
||||
QString fl = ui->lineKSearch->text();
|
||||
int lc = ui->treeK->topLevelItemCount();
|
||||
for (int i = 0; i < lc; ++i) {
|
||||
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
|
||||
if (ti->text(1).isEmpty() && he)
|
||||
ti->setHidden(true);
|
||||
else
|
||||
if (fl.isEmpty())
|
||||
ti->setHidden(false);
|
||||
else
|
||||
ti->setHidden(!ti->text(0).contains(fl, Qt::CaseInsensitive) &&
|
||||
!ti->text(1).contains(fl, Qt::CaseInsensitive) &&
|
||||
!ti->text(2).contains(fl, Qt::CaseInsensitive) &&
|
||||
!ti->text(3).contains(fl, Qt::CaseInsensitive) &&
|
||||
!ti->text(4).contains(fl, Qt::CaseInsensitive));
|
||||
if (hn)
|
||||
if (ti->data(0, Qt::UserRole).toBool())
|
||||
ti->setHidden(true);
|
||||
if (hs) {
|
||||
ti->data(2, Qt::DisplayRole).toDouble(&ok);
|
||||
if (!ok)
|
||||
ti->setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::calculate() {
|
||||
calculated.clear();
|
||||
ui->treeK->setUpdatesEnabled(false);
|
||||
ui->treeK->blockSignals(true);
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
progress(0, 100);
|
||||
ui->buttonCalculate->setEnabled(false);
|
||||
QApplication::processEvents();
|
||||
for (int i = 0; i < K.size_s(); ++i) {
|
||||
ui->treeK->topLevelItem(i)->setToolTip(2, QString());
|
||||
ui->treeK->topLevelItem(i)->setToolTip(3, QString());
|
||||
}
|
||||
for (int i = 0; i < K.size_s(); ++i) {
|
||||
progress(i, K.size_s());
|
||||
calculateExpression(i, QVector<int>());
|
||||
}
|
||||
ui->buttonCalculate->setEnabled(true);
|
||||
ui->progress->setValue(100);
|
||||
QApplication::restoreOverrideCursor();
|
||||
ui->treeK->blockSignals(false);
|
||||
ui->treeK->setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
bool KX_Pult::calculateExpression(int i, QVector<int> trace) {
|
||||
if (calculated.contains(i)) return true;
|
||||
trace << i;
|
||||
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
|
||||
QString expr = ti->text(2);
|
||||
if (expr.isEmpty() || expr == "0" || expr == "0,00000000" || expr == "0.00000000") {
|
||||
markNormal(ti);
|
||||
calculated << i;
|
||||
K[i] = 0.;
|
||||
ti->setText(3, "0");
|
||||
return true;
|
||||
}
|
||||
//ti->setToolTip(2, QString());
|
||||
if (!eval.check(expr)) {
|
||||
markError(ti, eval.error());
|
||||
return false;
|
||||
}
|
||||
foreach (const QString & n, knames_sort) {
|
||||
if (expr.contains(n)) {
|
||||
int ki = knames.value(n, -1);
|
||||
if (trace.contains(ki)) {
|
||||
QString strace;
|
||||
trace << ki;
|
||||
for (int j = 0; j < trace.size(); ++j) {
|
||||
//calculated << trace[j];
|
||||
if (j > 0) strace += " -> ";
|
||||
strace += "k" + QString::number(trace[j]);
|
||||
}
|
||||
for (int j = 0; j < trace.size(); ++j) {
|
||||
QTreeWidgetItem * pti = ui->treeK->topLevelItem(trace[j]);
|
||||
markError(pti, QString("Circular dependency: %1!").arg(strace));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (ki < 0) {
|
||||
markError(ti);
|
||||
return false;
|
||||
}
|
||||
if (calculated.contains(ki)) {
|
||||
eval.setVariable(n, K[ki]);
|
||||
} else {
|
||||
if (calculateExpression(ki, trace))
|
||||
eval.setVariable(n, K[ki]);
|
||||
else {
|
||||
markError(ti);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
markNormal(ti);
|
||||
calculated << i;
|
||||
complexd ret = eval.evaluate();
|
||||
K[i] = ret.real();
|
||||
ti->setText(3, QString::number(K[i]));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::markError(QTreeWidgetItem * item, const QString & tool_tip) {
|
||||
int cc = item->columnCount();
|
||||
for (int i = 0; i < cc; ++i)
|
||||
item->setBackgroundColor(i, QColor(255, 200, 200));
|
||||
if (item->toolTip(2).isEmpty())
|
||||
item->setToolTip(2, tool_tip);
|
||||
if (item->toolTip(3).isEmpty())
|
||||
item->setToolTip(3, tool_tip);
|
||||
item->setData(0, Qt::UserRole, false);
|
||||
item->setText(3, "Error");
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::markNormal(QTreeWidgetItem * item) {
|
||||
int cc = item->columnCount();
|
||||
for (int i = 0; i < cc; ++i)
|
||||
item->setBackground(i, Qt::NoBrush);
|
||||
item->setToolTip(2, QString());
|
||||
item->setToolTip(3, QString());
|
||||
item->setData(0, Qt::UserRole, true);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::progress(int val, int max) {
|
||||
if (ctm.elapsed() < 50) return;
|
||||
ctm.restart();
|
||||
ui->progress->setValue(qRound(val * 100. / max));
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::renew(bool write) {
|
||||
addToList(trUtf8("Update settings from \"%1\"").arg(PI2QString(config_)), Qt::darkMagenta);
|
||||
dir.setPath(config.getValue("x.output_dir", "./Experiments/").stringValue());
|
||||
setWindowTitle(config.getValue("title", "Noname").stringValue() + trUtf8(" - KX Pult"));
|
||||
//if (write) ui->configWidget->write();
|
||||
if (prot_x != 0) {
|
||||
prot_x->stop();
|
||||
delete prot_x;
|
||||
}
|
||||
if (prot_c != 0) {
|
||||
prot_c->stop();
|
||||
delete prot_c;
|
||||
}
|
||||
prot_x = new __KX_Protocol_X(config_, name_x);
|
||||
prot_c = new __KX_Protocol_C(config_, name_c);
|
||||
ui->graphic->setAutoXIncrement(prot_x->expectedFrequency() > 0. ? 1. / prot_x->expectedFrequency() : 1.);
|
||||
coeffs.renew();
|
||||
CONNECT1(void, bool, prot_x, received, this, received);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::toggledX(int index, bool on) {
|
||||
ui->graphic->setGraphicVisible(on, index);
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::changedX(int index, int num) {
|
||||
prot_x->to_x.x_num[index] = num;
|
||||
}
|
||||
|
||||
|
||||
void KX_Pult::commandClicked() {
|
||||
QPushButton * b = qobject_cast<QPushButton*>(sender());
|
||||
if (!b) return;
|
||||
prot_c->sendCommand(b->property("_command").toInt());
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
#ifndef KX_PULT_H
|
||||
#define KX_PULT_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QSpinBox>
|
||||
#include <QFont>
|
||||
#include <QRect>
|
||||
#include <QFile>
|
||||
#include <QVector>
|
||||
#include <QDir>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#include <QBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
#include <QTime>
|
||||
#include <QMenu>
|
||||
#include <QMetaObject>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QLabel>
|
||||
#include "kx_coeffs.h"
|
||||
#include "kx_protocol_x.h"
|
||||
#include "kx_protocol_c.h"
|
||||
#include "piqt.h"
|
||||
#include "session_manager.h"
|
||||
#include "qpievaluator.h"
|
||||
|
||||
|
||||
class XCheck: public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit XCheck(int index);
|
||||
QCheckBox check;
|
||||
QSpinBox spin;
|
||||
private:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
int index_;
|
||||
private slots:
|
||||
void spinChanged(int value) {check.setChecked(true); emit valueChanged(index_, value);}
|
||||
void checkChanged_(bool value) {emit checkChanged(index_, value);}
|
||||
signals:
|
||||
void valueChanged(int index, int value);
|
||||
void checkChanged(int index, bool on);
|
||||
};
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class KX_Pult;
|
||||
};
|
||||
|
||||
class KX_Pult: public QMainWindow, public PIObject
|
||||
{
|
||||
Q_OBJECT
|
||||
PIOBJECT(KX_Pult)
|
||||
public:
|
||||
KX_Pult();
|
||||
~KX_Pult();
|
||||
|
||||
private:
|
||||
struct KDesc {
|
||||
KDesc() {index = -1;}
|
||||
int index;
|
||||
QString name;
|
||||
QString type;
|
||||
QString comment;
|
||||
QString value;
|
||||
};
|
||||
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void timerEvent(QTimerEvent * );
|
||||
void setControlsEnable(bool enable);
|
||||
void setX(const KX_X_Data & data);
|
||||
void addToList(const QString & s, const QColor & c);
|
||||
QString getNewFileName(int inc);
|
||||
QColor invertColor(QColor col) {return QColor(255 - col.red(), 255 - col.green(), 255 - col.blue());}
|
||||
void stopWait();
|
||||
bool calculateExpression(int i, QVector<int> trace);
|
||||
void markError(QTreeWidgetItem * item, const QString & tool_tip = QString());
|
||||
void markNormal(QTreeWidgetItem * item);
|
||||
void progress(int val, int max);
|
||||
void clearSelected();
|
||||
QString typeName(const QString & n) const;
|
||||
int parseHeader(const QString & file, QMap<int, KDesc> & map);
|
||||
|
||||
EVENT_HANDLER1(void, received, bool, ok);
|
||||
EVENT_HANDLER(void, pip_sendFailed) {emit q_k_sendFailed();}
|
||||
EVENT_HANDLER(void, pip_sendSucceed) {emit q_k_sendSucceed();}
|
||||
EVENT_HANDLER(void, pip_receiveFailed) {emit q_k_receiveFailed();}
|
||||
EVENT_HANDLER(void, pip_receiveSucceed) {emit q_k_receiveSucceed();}
|
||||
|
||||
QVector<XCheck * > checks;
|
||||
QVector<QLabel * > values;
|
||||
|
||||
Ui::KX_Pult * ui;
|
||||
PIString config_, name_x, name_c;
|
||||
QDir dir;
|
||||
QString outdir, kdesc_file, cdesc_file;
|
||||
QFile file;
|
||||
QTime tm, ctm;
|
||||
QIcon icon_record, icon_stop;
|
||||
QTextStream stream;
|
||||
QTimer timer_diag;
|
||||
QMap<int, KDesc> kdesc, cdesc;
|
||||
QMap<QString, int> knames;
|
||||
QSet<int> calculated;
|
||||
QStringList knames_sort;
|
||||
QPIEvaluator eval;
|
||||
SessionManager session;
|
||||
QPIConfig config;
|
||||
QMenu log_menu;
|
||||
//QVector<float> k, x;
|
||||
KX_Coefficients coeffs;
|
||||
__KX_Protocol_X * prot_x;
|
||||
__KX_Protocol_C * prot_c;
|
||||
int csize, wcnt, timer, timer_update, clear_target;
|
||||
bool needWrite, isPause, need_update, show_x;
|
||||
|
||||
private slots:
|
||||
void loading(QPIConfig & conf);
|
||||
void saving(QPIConfig & conf);
|
||||
void updateGraph();
|
||||
void updateDiag();
|
||||
void updateKDesc(bool ask_move = false);
|
||||
void updateCDesc();
|
||||
void updateTree(bool move = false);
|
||||
void updateCommands();
|
||||
void filterTree();
|
||||
void calculate();
|
||||
void renew(bool write = true);
|
||||
void toggledX(int index, bool on);
|
||||
void changedX(int index, int num);
|
||||
void commandClicked();
|
||||
void k_sendFailed();
|
||||
void k_sendSucceed();
|
||||
void k_receiveFailed();
|
||||
void k_receiveSucceed();
|
||||
void on_spinBuffer_editingFinished();
|
||||
void on_buttonSendK_clicked();
|
||||
void on_buttonReceiveK_clicked();
|
||||
void on_buttonShowAll_clicked();
|
||||
void on_buttonHideAll_clicked();
|
||||
void on_buttonRead_clicked();
|
||||
void on_buttonWrite_clicked();
|
||||
void on_buttonResize_clicked();
|
||||
void on_buttonSetKDesc_clicked();
|
||||
void on_buttonReparseKDesc_clicked() {updateKDesc(true);}
|
||||
void on_buttonSetCDesc_clicked();
|
||||
void on_buttonReparseCDesc_clicked() {updateCDesc();}
|
||||
void on_buttonCalculate_clicked() {calculate();}
|
||||
void on_buttonApply_clicked() {renew();}
|
||||
void on_spinSize_valueChanged(int);
|
||||
void on_buttonPause_toggled(bool on) {isPause = on;}
|
||||
void on_buttonRecord_clicked();
|
||||
void on_treeK_itemClicked(QTreeWidgetItem * item, int column);
|
||||
void on_treeK_itemChanged(QTreeWidgetItem * item, int column);
|
||||
void on_actionClear_triggered();
|
||||
|
||||
signals:
|
||||
void q_k_sendFailed();
|
||||
void q_k_sendSucceed();
|
||||
void q_k_receiveFailed();
|
||||
void q_k_receiveSucceed();
|
||||
void recordStarted(const QString & fileName);
|
||||
void recordStopped(const QString & fileName);
|
||||
|
||||
};
|
||||
|
||||
#endif // KX_PULT_H
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>icons/dialog-close.png</file>
|
||||
<file>icons/edit-clear-.png</file>
|
||||
<file>icons/edit-guides.png</file>
|
||||
<file>icons/view-grid.png</file>
|
||||
<file>icons/zoom-fit-best.png</file>
|
||||
<file>icons/configure.png</file>
|
||||
<file>icons/alpha.png</file>
|
||||
<file>icons/document-save.png</file>
|
||||
<file>icons/edit-clear-locationbar-rtl.png</file>
|
||||
<file>icons/edit-find.png</file>
|
||||
<file>icons/list-add.png</file>
|
||||
<file>icons/edit-delete.png</file>
|
||||
<file>icons/item-add.png</file>
|
||||
<file>icons/item.png</file>
|
||||
<file>icons/node-add.png</file>
|
||||
<file>icons/node.png</file>
|
||||
<file>icons/edit-copy.png</file>
|
||||
<file>icons/edit-paste.png</file>
|
||||
<file>icons/expand_s_x.png</file>
|
||||
<file>icons/expand_s_y.png</file>
|
||||
<file>icons/expand_x.png</file>
|
||||
<file>icons/expand_y.png</file>
|
||||
<file>icons/media-playback-pause.png</file>
|
||||
<file>icons/media-playback-stop.png</file>
|
||||
<file>icons/media-record.png</file>
|
||||
<file>icons/application-exit.png</file>
|
||||
<file>icons/document-save-.png</file>
|
||||
<file>icons/view-refresh.png</file>
|
||||
<file>icons/document-open.png</file>
|
||||
<file>icons/archive-extract.png</file>
|
||||
<file>icons/document-export.png</file>
|
||||
<file>icons/document-import.png</file>
|
||||
<file>icons/zoom-fit-height.png</file>
|
||||
<file>icons/layer-visible-off.png</file>
|
||||
<file>icons/layer-visible-on.png</file>
|
||||
<file>icons/accessories-calculator.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
1311
kx_utils/kx_pult.ui
@@ -1,1311 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KX_Pult</class>
|
||||
<widget class="QMainWindow" name="KX_Pult">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1759</width>
|
||||
<height>852</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>KX Pult</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Coefficients (K)</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="buttonReparseKDesc">
|
||||
<property name="text">
|
||||
<string>Reparse K desc</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/view-refresh.png</normaloff>:/icons/view-refresh.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QPushButton" name="buttonResize">
|
||||
<property name="text">
|
||||
<string>Resize</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/zoom-fit-height.png</normaloff>:/icons/zoom-fit-height.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="buttonRead">
|
||||
<property name="text">
|
||||
<string>Read file K</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/archive-extract.png</normaloff>:/icons/archive-extract.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="buttonSendK">
|
||||
<property name="text">
|
||||
<string>Send</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/document-export.png</normaloff>:/icons/document-export.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="buttonWrite">
|
||||
<property name="text">
|
||||
<string>Write file K</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="5">
|
||||
<widget class="QListWidget" name="list">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="buttonReceiveK">
|
||||
<property name="text">
|
||||
<string>Receive</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/document-import.png</normaloff>:/icons/document-import.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="buttonSetKDesc">
|
||||
<property name="text">
|
||||
<string>Set K desc file ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="spinSize">
|
||||
<property name="maximum">
|
||||
<number>65536</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="labelWait">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkKHideEmpty">
|
||||
<property name="text">
|
||||
<string>Hide empty</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkKHideExpressions">
|
||||
<property name="text">
|
||||
<string>Hide expressions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkKHideNormal">
|
||||
<property name="text">
|
||||
<string>Hide without errors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="pixmap">
|
||||
<pixmap resource="kx_pult.qrc">:/icons/edit-find.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string> Search:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="CLineEdit" name="lineKSearch">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkKAutoCalculate">
|
||||
<property name="text">
|
||||
<string>Auto calculate</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonCalculate">
|
||||
<property name="toolTip">
|
||||
<string>Calculate</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Calculate</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/accessories-calculator.png</normaloff>:/icons/accessories-calculator.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progress">
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="format">
|
||||
<string>Calculate %p%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeK">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>200</number>
|
||||
</attribute>
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>20</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Index</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Expression</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Calculated</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Comment</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>Commands (C)</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonSetCDesc">
|
||||
<property name="text">
|
||||
<string>Set C desc file ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonReparseCDesc">
|
||||
<property name="text">
|
||||
<string>Reparse C desc</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/view-refresh.png</normaloff>:/icons/view-refresh.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupCommands">
|
||||
<property name="title">
|
||||
<string>Commands</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="layout_">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1370</width>
|
||||
<height>655</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="layoutCommands"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>66</width>
|
||||
<height>441</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Graphics (X)</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetChecks" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="horizontalSpacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonShowAll">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show all</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/layer-visible-on.png</normaloff>:/icons/layer-visible-on.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonHideAll">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Hide all</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/layer-visible-off.png</normaloff>:/icons/layer-visible-off.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonRecord">
|
||||
<property name="text">
|
||||
<string>Start record</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/media-record.png</normaloff>:/icons/media-record.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonPause">
|
||||
<property name="text">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/media-playback-pause.png</normaloff>:/icons/media-playback-pause.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Show</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinHistory">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> с</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinBuffer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> с</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>60.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Graphic" name="graphic">
|
||||
<property name="buttons">
|
||||
<set>Graphic::Autofit|Graphic::BorderInputs|Graphic::Clear|Graphic::Configure|Graphic::CursorAxis|Graphic::Grid|Graphic::OnlyExpandX|Graphic::OnlyExpandY|Graphic::Save</set>
|
||||
</property>
|
||||
<property name="borderInputsVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="legendVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="historySize">
|
||||
<double>60.000000000000000</double>
|
||||
</property>
|
||||
<property name="maxVisibleTime">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Configuration</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>K</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="formAlignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>receiver:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="labelKReceiver">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>sender:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="labelKSender">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>sended count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="spinKSended">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QSpinBox" name="spinKReceived">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>wrong received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="spinKWrong">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="labelKType">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelKType_2">
|
||||
<property name="text">
|
||||
<string>address K:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="labelKAddr">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="labelKAddrPult">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>missed received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QSpinBox" name="spinKMissed">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelKType_3">
|
||||
<property name="text">
|
||||
<string>address pult:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>X</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="formAlignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>receiver:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="labelXReceiver">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>sender:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="labelXSender">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelKType_4">
|
||||
<property name="text">
|
||||
<string>type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="labelXType">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelKType_5">
|
||||
<property name="text">
|
||||
<string>address X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelKType_6">
|
||||
<property name="text">
|
||||
<string>address pult:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="labelXAddrPult">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>sended count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="spinXSended">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QSpinBox" name="spinXReceived">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>wrong received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="spinXWrong">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="labelXAddr">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>missed received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QSpinBox" name="spinXMissed">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>C</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="formAlignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>receiver:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="labelCReceiver">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>sender:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="labelCSender">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelKType_7">
|
||||
<property name="text">
|
||||
<string>type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="labelCType">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelKType_8">
|
||||
<property name="text">
|
||||
<string>address C:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelKType_9">
|
||||
<property name="text">
|
||||
<string>address pult:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="labelCAddrPult">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="text">
|
||||
<string>sended count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="spinCSended">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QSpinBox" name="spinCReceived">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>wrong received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="spinCWrong">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="labelCAddr">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="text">
|
||||
<string>missed received count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QSpinBox" name="spinCMissed">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPIConfigWidget" name="configWidget">
|
||||
<property name="readOnlyName">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnlyType">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnlyComment">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="columnTypeVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>20</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonApply">
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<action name="actionClear">
|
||||
<property name="icon">
|
||||
<iconset resource="kx_pult.qrc">
|
||||
<normaloff>:/icons/edit-clear-.png</normaloff>:/icons/edit-clear-.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Graphic</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>graphic.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>CLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>clineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QPIConfigWidget</class>
|
||||
<extends>QTreeWidget</extends>
|
||||
<header>qpiconfigwidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="kx_pult.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>spinHistory</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>graphic</receiver>
|
||||
<slot>setMaxVisibleTime(double)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>919</x>
|
||||
<y>107</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>932</x>
|
||||
<y>132</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1,10 +0,0 @@
|
||||
#include <QtGui/QApplication>
|
||||
#include "kx_pult.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QApplication a(argc, argv);
|
||||
KX_Pult w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
cmake -G "MinGW Makefiles" -DLIB=1 && make install . %*
|
||||
@@ -1,718 +0,0 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Protocol, input/output channel (COM, UDP)
|
||||
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piprotocol.h"
|
||||
|
||||
/** \class PIProtocol
|
||||
* \brief
|
||||
* \details
|
||||
* \section PIProtocol_sec0 Synopsis
|
||||
*
|
||||
*
|
||||
*
|
||||
* */
|
||||
|
||||
/// DEPRECATED
|
||||
PIProtocol::PIProtocol(const PIString & config, const PIString & name_, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_): PIObject() {
|
||||
init();
|
||||
protName = name_;
|
||||
PIObject::setName(name_);
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
if (!conf.isOpened()) {
|
||||
piCoutObj << "Can`t open \"" << config << "\"!";
|
||||
devReceiverState = devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
PIConfig::Entry & b(conf.getValue(name_)),
|
||||
& rb(b.getValue("receiver")),
|
||||
& sb(b.getValue("sender"));
|
||||
|
||||
init_receiver(b, rb, config);
|
||||
init_sender(b, sb, config);
|
||||
|
||||
headerPtr = (uchar * )recHeaderPtr;
|
||||
headerSize = recHeaderSize;
|
||||
dataPtr = (uchar * )recDataPtr;
|
||||
dataSize = recDataSize;
|
||||
sendDataPtr = (uchar * )sendDataPtr_;
|
||||
sendDataSize = sendDataSize_;
|
||||
packet_ext->setHeader(PIByteArray(recHeaderPtr, recHeaderSize));
|
||||
packet_ext->setPayloadSize(recDataSize);
|
||||
packet_ext->setPacketSize(recDataSize);
|
||||
packet_ext->setSplitMode(PIPacketExtractor::Header);
|
||||
bool null_h = (recHeaderPtr == 0 || recHeaderSize == 0), null_d = (recDataPtr == 0 || recDataSize == 0);
|
||||
if (null_h && null_d) packet_ext->setSplitMode(PIPacketExtractor::None);
|
||||
else {
|
||||
if (null_h) packet_ext->setSplitMode(PIPacketExtractor::Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIProtocol::~PIProtocol() {
|
||||
delete diagTimer;
|
||||
delete sendTimer;
|
||||
delete secTimer;
|
||||
delete packet_ext;
|
||||
if (eth != 0) delete eth;
|
||||
if (ser != 0) delete ser;
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::init() {
|
||||
packet_ext = new PIPacketExtractor(0, PIPacketExtractor::None);
|
||||
packet_ext->setThreadedReadData(this);
|
||||
packet_ext->setThreadedReadSlot(receiveEvent);
|
||||
packet_ext->setHeaderCheckSlot(headerValidateEvent);
|
||||
packet_ext->setName("__S__PIProtocol::packet_ext");
|
||||
work = new_mp_prot = false;
|
||||
eth = 0;
|
||||
ser = 0;
|
||||
ret_func = 0;
|
||||
mp_owner = 0;
|
||||
net_diag = PIProtocol::Unknown;
|
||||
cur_pckt = 0;
|
||||
packets[0] = packets[1] = pckt_cnt = pckt_cnt_max = 0;
|
||||
diagTimer = 0;
|
||||
timeout_ = 3.f;
|
||||
sendTimer = new PITimer(sendEvent, this);
|
||||
diagTimer = new PITimer(diagEvent, this);
|
||||
secTimer = new PITimer(secEvent, this);
|
||||
sendTimer->setName("__S__PIProtocol::sendTimer");
|
||||
diagTimer->setName("__S__PIProtocol::diagTimer");
|
||||
secTimer->setName("__S__PIProtocol::secTimer");
|
||||
wrong_count = receive_count = send_count = missed_count = 0;
|
||||
packets_in_sec = packets_out_sec = bytes_in_sec = bytes_out_sec = 0;
|
||||
immediate_freq = integral_freq = ifreq = 0.f;
|
||||
headerPtr = dataPtr = sendDataPtr = 0;
|
||||
headerSize = dataSize = sendDataSize = 0;
|
||||
type_rec = type_send = PIProtocol::None;
|
||||
devSenderState = devReceiverState = "Unknown";
|
||||
devSenderName = devReceiverName = "no device";
|
||||
secTimer->start(1000.);
|
||||
/*addEvent("receiver started");
|
||||
addEvent("receiver stopped");
|
||||
addEvent("sender started");
|
||||
addEvent("sender stopped");
|
||||
addEvent<bool>("received");
|
||||
addEvent<PIProtocol::Quality>("quality changed");
|
||||
addEventHandler<float>(HANDLER(PIProtocol, startReceive));
|
||||
addEventHandler<float>(HANDLER(PIProtocol, startSend));
|
||||
addEventHandler(HANDLER(PIProtocol, start));
|
||||
addEventHandler(HANDLER(PIProtocol, stopReceive));
|
||||
addEventHandler(HANDLER(PIProtocol, stopSend));
|
||||
addEventHandler(HANDLER(PIProtocol, stop));*/
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::init_sender(PIConfig::Entry & b, PIConfig::Entry & sb, const PIString & config) {
|
||||
int ps, gps;
|
||||
bool ok, gok, flag, gflag, has_dev = false;
|
||||
float freq, gfreq;
|
||||
PIFlags<PISerial::Parameters> pp(0);
|
||||
PIString dev, gdev;
|
||||
|
||||
if (sb.isEntryExists("ip") && sb.isEntryExists("device")) {
|
||||
piCoutObj << "Ambiguous sender type in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
dev = sb.getValue("ip", "", &ok);
|
||||
gdev = b.getValue("ip", "", &gok);
|
||||
has_dev = false;
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
piCoutObj << "Ambiguous sender type in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
ps = sb.getValue("port", 0, &ok);
|
||||
gps = b.getValue("port", 0, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
piCoutObj << "Ambiguous send port in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet();
|
||||
eth->setName("__S__PIProtocol::eth");
|
||||
setSenderAddress(dev, ps);
|
||||
//setReceiverAddress(dev, ps);
|
||||
has_dev = true;
|
||||
flag = sb.getValue("reconnectEnabled", true, &ok);
|
||||
gflag = b.getValue("reconnectEnabled", true, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCoutObj << "Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
eth->setReopenEnabled(flag);
|
||||
}
|
||||
freq = sb.getValue("reconnectTimeout", 1., &ok);
|
||||
gfreq = b.getValue("reconnectTimeout", 1., &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) freq = gfreq;
|
||||
if (gok && ok && (freq != gfreq)) {
|
||||
piCoutObj << "Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
eth->setReopenTimeout(freq * 1000);
|
||||
}
|
||||
/*if (sendDataPtr_ == 0)
|
||||
piCoutObj << "Warning: null send data pointer!";
|
||||
if (sendDataSize_ == 0)
|
||||
piCoutObj << "Warning: null send data size!";*/
|
||||
} else {
|
||||
piCoutObj << "Can`t find \"" << name() << ".sender.port\" or \"" << name() << ".port\" in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
}
|
||||
dev = sb.getValue("device", "", &ok);
|
||||
gdev = b.getValue("device", "", &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
piCoutObj << "Ambiguous sender type in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
ps = sb.getValue("speed", 0, &ok);
|
||||
gps = b.getValue("speed", 0, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
piCoutObj << "Ambiguous send \"speed\" in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
flag = sb.getValue("parity", false, &ok);
|
||||
gflag = b.getValue("parity", false, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCoutObj << "Ambiguous send \"parity\" in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp.setFlag(PISerial::ParityControl, flag);
|
||||
}
|
||||
flag = sb.getValue("twoStopBits", false, &ok);
|
||||
gflag = b.getValue("twoStopBits", false, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCoutObj << "Ambiguous send \"twoStopBits\" parity in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp.setFlag(PISerial::TwoStopBits, flag);
|
||||
}
|
||||
} else {
|
||||
piCoutObj << "Can`t find \"" << name() << ".sender.speed\" or \"" << name() << ".speed\" in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
type_send = PIProtocol::Serial;
|
||||
if (ser == 0) ser = new PISerial(dev);
|
||||
ser->setName("__S__PIProtocol::ser");
|
||||
setSenderDevice(dev, (PISerial::Speed)ps);
|
||||
ser->setOutSpeed((PISerial::Speed)ps);
|
||||
ser->setParameters(pp);
|
||||
has_dev = true;
|
||||
/*if (sendDataPtr_ == 0)
|
||||
piCoutObj << "Warning: null send data pointer!";
|
||||
if (sendDataSize_ == 0)
|
||||
piCoutObj << "Warning: null send data size!";*/
|
||||
}
|
||||
freq = sb.getValue("frequency", -1.f, &ok);
|
||||
gfreq = b.getValue("frequency", -1.f, &gok);
|
||||
if (gok && !ok) freq = gfreq;
|
||||
if (gok && ok && (freq != gfreq)) {
|
||||
piCoutObj << "Ambiguous sender frequency in \"" << config << "\"!";
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
if (freq > 0.f && !has_dev)
|
||||
piCoutObj << "Warning: no sender device and not null send frequency!";
|
||||
setSenderFrequency(freq);
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const PIString & config) {
|
||||
int ps, gps;
|
||||
bool ok, gok, flag, gflag, has_dev = false;
|
||||
float freq, gfreq;
|
||||
PIFlags<PISerial::Parameters> pp(0);
|
||||
PIString dev, gdev;
|
||||
|
||||
if (rb.isEntryExists("ip") && rb.isEntryExists("device")) {
|
||||
piCoutObj << "Ambiguous receiver type in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
dev = rb.getValue("ip", "", &ok);
|
||||
gdev = b.getValue("ip", "", &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
piCoutObj << "Ambiguous receiver type in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
ps = rb.getValue("port", 0, &ok);
|
||||
gps = b.getValue("port", 0, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
piCoutObj << "Ambiguous receive port in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
type_rec = PIProtocol::Ethernet;
|
||||
eth = new PIEthernet();
|
||||
eth->setName("__S__PIProtocol::eth");
|
||||
packet_ext->setDevice(eth);
|
||||
//setSenderAddress(dev, ps);
|
||||
setReceiverAddress(dev, ps);
|
||||
has_dev = true;
|
||||
flag = rb.getValue("reconnectEnabled", true, &ok);
|
||||
gflag = b.getValue("reconnectEnabled", true, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCoutObj << "Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
eth->setReopenEnabled(flag);
|
||||
}
|
||||
freq = rb.getValue("reconnectTimeout", 1., &ok);
|
||||
gfreq = b.getValue("reconnectTimeout", 1., &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) freq = gfreq;
|
||||
if (gok && ok && (freq != gfreq)) {
|
||||
piCoutObj << "Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
eth->setReopenTimeout(freq * 1000);
|
||||
}
|
||||
/*if (recDataPtr == 0)
|
||||
piCoutObj << "Warning: null receive data pointer!";
|
||||
if (recDataSize == 0)
|
||||
piCoutObj << "Warning: null receive data size!";*/
|
||||
} else {
|
||||
piCoutObj << "Can`t find \"" << name() << ".receiver.port\" or \"" << name() << ".port\" in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
}
|
||||
dev = rb.getValue("device", "", &ok);
|
||||
gdev = b.getValue("device", "", &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
piCoutObj << "Ambiguous receiver type in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
ps = rb.getValue("speed", 0, &ok);
|
||||
gps = b.getValue("speed", 0, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
piCoutObj << "Ambiguous receive \"speed\" in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
flag = rb.getValue("parity", false, &ok);
|
||||
gflag = b.getValue("parity", false, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCoutObj << "Ambiguous receive \"parity\" in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp.setFlag(PISerial::ParityControl, flag);
|
||||
}
|
||||
flag = rb.getValue("twoStopBits", false, &ok);
|
||||
gflag = b.getValue("twoStopBits", false, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCoutObj << "Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp.setFlag(PISerial::TwoStopBits, flag);
|
||||
}
|
||||
type_rec = PIProtocol::Serial;
|
||||
type_send = PIProtocol::Serial;
|
||||
ser = new PISerial(dev);
|
||||
ser->setName("__S__PIProtocol::ser");
|
||||
packet_ext->setDevice(ser);
|
||||
//setSenderDevice(dev, (PISerial::Speed)ps);
|
||||
setReceiverDevice(dev, (PISerial::Speed)ps);
|
||||
ser->setInSpeed((PISerial::Speed)ps);
|
||||
ser->setParameters(pp);
|
||||
ps = rb.getValue("vtime", 1, &ok);
|
||||
gps = b.getValue("vtime", 1, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
piCoutObj << "Ambiguous receive \"vtime\" in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
ser->setVTime(ps);
|
||||
}
|
||||
has_dev = true;
|
||||
/*if (recDataPtr == 0)
|
||||
piCoutObj << "Warning: null receive data pointer!";
|
||||
if (recDataSize == 0)
|
||||
piCoutObj << "Warning: null receive data size!";*/
|
||||
} else {
|
||||
piCoutObj << "Can`t find \"" << name() << ".receiver.speed\" or \"" << name() << ".speed\" in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
}
|
||||
freq = rb.getValue("frequency", -1.f, &ok);
|
||||
gfreq = b.getValue("frequency", -1.f, &gok);
|
||||
if (gok && !ok) freq = gfreq;
|
||||
if (gok && ok && (freq != gfreq)) {
|
||||
piCoutObj << "Ambiguous expected frequency in \"" << config << "\"!";
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
if (freq > 0.f && !has_dev)
|
||||
piCoutObj << "Warning: no receiver device and not null expected frequency!";
|
||||
float tm = b.getValue("disconnectTimeout", 3.f);
|
||||
if (tm <= 0.f)
|
||||
piCoutObj << "Warning: diconnect timeout <= 0 s!";
|
||||
timeout_ = (tm < 0.f) ? 0.f : tm;
|
||||
setExpectedFrequency(freq);
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force) {
|
||||
if (force) {
|
||||
type_send = type_rec = PIProtocol::Serial;
|
||||
if (ser == 0) {
|
||||
ser = new PISerial();
|
||||
ser->setName("__S__PIProtocol::ser");
|
||||
packet_ext->setDevice(ser);
|
||||
}
|
||||
}
|
||||
if (type_rec == PIProtocol::Serial && ser != 0) {
|
||||
ser->setDevice(device);
|
||||
ser->setSpeed(speed);
|
||||
devReceiverName = device;
|
||||
devSenderName = device;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) {
|
||||
if (force) {
|
||||
type_rec = PIProtocol::Ethernet;
|
||||
if (eth == 0) {
|
||||
eth = new PIEthernet();
|
||||
eth->setName("__S__PIProtocol::eth");
|
||||
packet_ext->setDevice(eth);
|
||||
}
|
||||
}
|
||||
if (type_rec == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setReadAddress(ip, port);
|
||||
if (ip.trimmed().isEmpty()) devReceiverName = "no ip";
|
||||
else devReceiverName = ip + ":" + PIString::fromNumber(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed, bool force) {
|
||||
if (force) {
|
||||
type_send = type_rec = PIProtocol::Serial;
|
||||
if (ser == 0) ser = new PISerial();
|
||||
ser->setName("__S__PIProtocol::ser");
|
||||
}
|
||||
if (type_send == PIProtocol::Serial && ser != 0) {
|
||||
ser->setDevice(device);
|
||||
ser->setSpeed(speed);
|
||||
ser->open();
|
||||
devSenderName = device;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) {
|
||||
if (force) {
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet();
|
||||
eth->setName("__S__PIProtocol::eth");
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setSendAddress(ip, port);
|
||||
if (ip.isEmpty()) devSenderName = "no ip";
|
||||
else devSenderName = ip + ":" + PIString::fromNumber(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setSenderIP(const PIString & ip, bool force) {
|
||||
if (force) {
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet();
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setSendIP(ip);
|
||||
if (ip.isEmpty()) devSenderName = "no ip";
|
||||
else devSenderName = ip + ":" + PIString::fromNumber(eth->sendPort());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setSenderPort(int port, bool force) {
|
||||
if (force) {
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet();
|
||||
eth->setName("__S__PIProtocol::eth");
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setSendPort(port);
|
||||
if (eth->sendIP().isEmpty()) devSenderName = "no ip";
|
||||
else devSenderName = eth->sendIP() + ":" + PIString::fromNumber(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setExpectedFrequency(float frequency) {
|
||||
exp_freq = frequency;
|
||||
changeDisconnectTimeout();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::changeDisconnectTimeout() {
|
||||
pckt_cnt_max = int(piRound(timeout_ * exp_freq));
|
||||
if (pckt_cnt_max < 3) pckt_cnt_max = 3;
|
||||
last_packets.resize(pckt_cnt_max);
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::startReceive(float exp_frequency) {
|
||||
if (exp_frequency > 0.f) exp_freq = exp_frequency;
|
||||
//if (type_rec == PIProtocol::Serial) ser->start();
|
||||
//if (type_rec == PIProtocol::Ethernet) eth->start();
|
||||
packet_ext->startThreadedRead();
|
||||
msleep(1);
|
||||
check_state();
|
||||
if (exp_freq <= 0.f) return;
|
||||
setExpectedFrequency(exp_freq);
|
||||
diagTimer->start(1000. / exp_freq);
|
||||
diag_tm.reset();
|
||||
receiverStarted();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::startSend(float frequency) {
|
||||
//cout << "** start send " << send_freq << ", " << frequency << endl;
|
||||
if (frequency > 0.f) send_freq = frequency;
|
||||
msleep(1);
|
||||
check_state();
|
||||
if (send_freq <= 0.f) return;
|
||||
sendTimer->start(1000. / send_freq);
|
||||
diag_tm.reset();
|
||||
senderStarted();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::stopReceive() {
|
||||
//if (type_rec == PIProtocol::Serial) ser->stop();
|
||||
//if (type_rec == PIProtocol::Ethernet) eth->stop();
|
||||
packet_ext->stop();
|
||||
diagTimer->stop();
|
||||
receiverStopped();
|
||||
}
|
||||
|
||||
|
||||
bool PIProtocol::receiveEvent(void * t, uchar * data, int size) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
if (!p->receive(data, size)) return false;
|
||||
p->work = true;
|
||||
//p->lock();
|
||||
if (p->validate()) {
|
||||
p->received(true);
|
||||
//p->unlock();
|
||||
p->ifreq = p->diag_tm.elapsed_m();
|
||||
if (p->ifreq > 0.) p->ifreq = 1000. / p->ifreq;
|
||||
p->diag_tm.reset();
|
||||
p->receive_count++;
|
||||
p->packets_in_sec++;
|
||||
p->bytes_in_sec += size;
|
||||
p->cur_pckt = 1;
|
||||
if (p->ret_func != 0) p->ret_func(p);
|
||||
if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, true, data, size);
|
||||
return true;
|
||||
}
|
||||
p->received(false);
|
||||
//p->unlock();
|
||||
p->wrong_count++;
|
||||
if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, false, data, size);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::diagEvent(void * t, int) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
p->calc_freq();
|
||||
p->calc_diag();
|
||||
p->check_state();
|
||||
if (p->ser != 0) p->missed_count = p->packet_ext->missedPackets();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::secEvent(void * t, int ) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
p->speedIn = PIString::readableSize(p->bytes_in_sec) + "/s";
|
||||
p->speedOut = PIString::readableSize(p->bytes_out_sec) + "/s";
|
||||
p->bytes_in_sec = p->bytes_out_sec = p->packets_in_sec = p->packets_out_sec = 0;
|
||||
if (p->ser != 0) p->missed_count = p->packet_ext->missedPackets();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::calc_diag() {
|
||||
PIProtocol::Quality diag;
|
||||
if (!work) {
|
||||
diag = PIProtocol::Unknown;
|
||||
return;
|
||||
}
|
||||
if (pckt_cnt < pckt_cnt_max) {
|
||||
last_packets[pckt_cnt] = cur_pckt;
|
||||
pckt_cnt++;
|
||||
} else {
|
||||
packets[(int)last_packets.back()]--;
|
||||
if (!last_packets.isEmpty()) last_packets.pop_back();
|
||||
last_packets.push_front(cur_pckt);
|
||||
}
|
||||
packets[(int)cur_pckt]++;
|
||||
cur_pckt = 0;
|
||||
float good_percents;
|
||||
good_percents = (float)packets[1] / pckt_cnt * 100.f;
|
||||
if (good_percents == 0.f) diag = PIProtocol::Failure;
|
||||
else if (good_percents <= 20.f) diag = PIProtocol::Bad;
|
||||
else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average;
|
||||
else diag = PIProtocol::Good;
|
||||
if (diag != net_diag) {
|
||||
qualityChanged(diag, net_diag);
|
||||
net_diag = diag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::calc_freq() {
|
||||
float tf;// = float(1000.f / diagTimer->elapsed_m());
|
||||
tf = immediate_freq = ifreq;
|
||||
ifreq = 0.f;
|
||||
if (last_freq.size_s() >= pckt_cnt_max && last_freq.size_s() > 0) last_freq.pop_front();
|
||||
last_freq.push_back(tf);
|
||||
tf = last_freq[0];
|
||||
for (uint i = 1; i < last_freq.size(); ++i)
|
||||
tf += last_freq[i];
|
||||
integral_freq = tf / last_freq.size();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::check_state() {
|
||||
if (type_rec == PIProtocol::Serial) {
|
||||
if (ser != 0) {
|
||||
if (ser->isOpened()) devReceiverState = "Opened";
|
||||
else devReceiverState = "Not opened";
|
||||
}
|
||||
else devReceiverState = "Not exists";
|
||||
}
|
||||
if (type_rec == PIProtocol::Ethernet) {
|
||||
if (eth != 0) {
|
||||
if (eth->isOpened()) devReceiverState = "Opened";
|
||||
else devReceiverState = "Not opened";
|
||||
}
|
||||
else devReceiverState = "Not exists";
|
||||
}
|
||||
if (type_send == PIProtocol::Serial) {
|
||||
if (ser != 0) {
|
||||
if (ser->isOpened()) devSenderState = "Opened";
|
||||
else devSenderState = "Not opened";
|
||||
}
|
||||
else devSenderState = "Not exists";
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet) {
|
||||
if (eth != 0) {
|
||||
if (eth->isOpened()) devSenderState = "Opened";
|
||||
else devSenderState = "Not opened";
|
||||
}
|
||||
else devSenderState = "Not exists";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::send(const void * data, int size, bool direct) {
|
||||
if (!direct) {
|
||||
if (data == 0 || size == 0) return;
|
||||
if (!aboutSend()) return;
|
||||
}
|
||||
if (type_send == PIProtocol::Serial)
|
||||
if (ser->send(data, size)) {
|
||||
send_count++;
|
||||
packets_out_sec++;
|
||||
bytes_out_sec += size;
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet)
|
||||
if (eth->send(data, size)) {
|
||||
send_count++;
|
||||
packets_out_sec++;
|
||||
bytes_out_sec += size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::send() {
|
||||
//lock();
|
||||
//memcpy(packet, sendDataPtr, sendDataSize);
|
||||
//unlock();
|
||||
if (!aboutSend()) return;
|
||||
if (sendDataPtr == 0 || sendDataSize == 0) return;
|
||||
if (type_send == PIProtocol::Serial)
|
||||
if (ser->send(sendDataPtr, sendDataSize)) {
|
||||
send_count++;
|
||||
packets_out_sec++;
|
||||
bytes_out_sec += sendDataSize;
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet)
|
||||
if (eth->send(sendDataPtr, sendDataSize)) {
|
||||
send_count++;
|
||||
packets_out_sec++;
|
||||
bytes_out_sec += sendDataSize;
|
||||
}
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
/*! \file piprotocol.h
|
||||
* \brief Highly configurable from file I/O channel
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Protocol, input/output channel (COM, UDP)
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIPROTOCOL_H
|
||||
#define PIPROTOCOL_H
|
||||
|
||||
#include "piserial.h"
|
||||
#include "piethernet.h"
|
||||
#include "pipacketextractor.h"
|
||||
#include "pitimer.h"
|
||||
#include "piconfig.h"
|
||||
#include "pifile.h"
|
||||
|
||||
class PIProtocol; /// DEPRECATED
|
||||
|
||||
class PIP_EXPORT PIMultiProtocolBase: protected PIObject /// DEPRECATED
|
||||
{
|
||||
PIOBJECT_SUBCLASS(PIMultiProtocolBase, PIObject)
|
||||
friend class PIProtocol;
|
||||
public:
|
||||
PIMultiProtocolBase() {;} /// DEPRECATED
|
||||
virtual ~PIMultiProtocolBase() {;}
|
||||
|
||||
protected:
|
||||
virtual void received(PIProtocol * prot, bool corrected, uchar * data, int size) {;}
|
||||
|
||||
private:
|
||||
static void receiveEvent(PIMultiProtocolBase * p, PIProtocol * prot, bool corrected, uchar * data, int size) {p->mutex_receive.lock(); p->received(prot, corrected, data, size); p->mutex_receive.unlock();}
|
||||
|
||||
PIMutex mutex_receive;
|
||||
|
||||
};
|
||||
|
||||
typedef void (*ReceiveFunc)(void * );
|
||||
|
||||
/// events:
|
||||
/// void receiverStarted()
|
||||
/// void receiverStopped()
|
||||
/// void senderStarted()
|
||||
/// void senderStopped()
|
||||
/// void received(bool validate_is_ok)
|
||||
/// void qualityChanged(PIProtocol::Quality old_quality, PIProtocol::Quality new_quality)
|
||||
///
|
||||
/// handlers:
|
||||
/// void startReceive(float exp_frequency = -1.f)
|
||||
/// void stopReceive()
|
||||
/// void startSend(float frequency = -1.f)
|
||||
/// void stopSend()
|
||||
/// void start()
|
||||
/// void stop()
|
||||
/// void send()
|
||||
/// void send(const void * data, int size, bool direct = false)
|
||||
class PIP_EXPORT PIProtocol: public PIObject /// DEPRECATED
|
||||
{
|
||||
PIOBJECT_SUBCLASS(PIProtocol, PIObject)
|
||||
friend class PIMultiProtocolBase;
|
||||
friend class PIMultiProtocol;
|
||||
enum Type {None, Serial, Ethernet};
|
||||
public:
|
||||
|
||||
//! Contructs an empty unconfigured protocol
|
||||
PIProtocol(): PIObject() {init();} /// DEPRECATED
|
||||
|
||||
//! Contructs protocol configured from file "config", config file section "name"
|
||||
PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0,
|
||||
void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0); // from config
|
||||
|
||||
virtual ~PIProtocol();
|
||||
|
||||
//! Connection quality
|
||||
enum Quality {
|
||||
Unknown /** Unknown, no one packet received yet */ = 1,
|
||||
Failure /** No connection, no one correct packet received for last period */ = 2,
|
||||
Bad /** Bad connection, correct packets received <= 20% */ = 3,
|
||||
Average /** Average connection, correct packets received > 20% and <= 80% */ = 4,
|
||||
Good /** Good connection, correct packets received > 80% */ = 5
|
||||
};
|
||||
|
||||
EVENT_HANDLER0(void, startReceive) {startReceive(-1.f);}
|
||||
EVENT_HANDLER1(void, startReceive, float, exp_frequency); // if "frequency = -1" used last passed value
|
||||
EVENT_HANDLER0(void, stopReceive);
|
||||
void setExpectedFrequency(float frequency); // for connection quality diagnostic
|
||||
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
||||
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setHeader(PIByteArray(headerPtr, headerSize)); packet_ext->setPayloadSize(dataSize); packet_ext->setPacketSize(dataSize);}
|
||||
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext->setHeader(PIByteArray(headerPtr, headerSize)); packet_ext->setPayloadSize(dataSize); packet_ext->setPacketSize(dataSize);}
|
||||
void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet
|
||||
void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
||||
float expectedFrequency() const {return exp_freq;}
|
||||
|
||||
EVENT_HANDLER0(void, startSend) {startSend(-1.f);} // if "frequency = -1" used last passed value
|
||||
EVENT_HANDLER1(void, startSend, float, frequency); // if "frequency = -1" used last passed value
|
||||
EVENT_HANDLER0(void, stopSend) {sendTimer->stop(); senderStopped();}
|
||||
void setSenderFrequency(float frequency) {send_freq = frequency;}
|
||||
void setSenderDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
||||
void setSenderData(void * dataPtr, int dataSize) {sendDataPtr = (uchar * )dataPtr; sendDataSize = dataSize;}
|
||||
void setSenderAddress(const PIString & ip, int port, bool force = false); // for Ethernet
|
||||
void setSenderIP(const PIString & ip, bool force = false); // for Ethernet
|
||||
void setSenderPort(int port, bool force = false); // for Ethernet
|
||||
void setSenderParameters(PIFlags<PISerial::Parameters> parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||
float senderFrequency() const {return send_freq;}
|
||||
|
||||
EVENT_HANDLER0(void, start) {startReceive(); startSend();}
|
||||
EVENT_HANDLER0(void, stop) {stopReceive(); stopSend();}
|
||||
EVENT_HANDLER0(void, send);
|
||||
EVENT_HANDLER2(void, send, const void *, data, int, size) {send(data, size, false);}
|
||||
EVENT_HANDLER3(void, send, const void *, data, int, size, bool, direct);
|
||||
|
||||
void setName(const PIString & name) {protName = name; PIObject::setName(name);}
|
||||
PIString name() const {return protName;}
|
||||
void setDisconnectTimeout(float timeout) {timeout_ = timeout; changeDisconnectTimeout();}
|
||||
float disconnectTimeout() const {return timeout_;}
|
||||
const float * disconnectTimeout_ptr() const {return &timeout_;}
|
||||
float immediateFrequency() const {return immediate_freq;}
|
||||
float integralFrequency() const {return integral_freq;}
|
||||
const float * immediateFrequency_ptr() const {return &immediate_freq;}
|
||||
const float * integralFrequency_ptr() const {return &integral_freq;}
|
||||
ullong receiveCountPerSec() const {return packets_in_sec;}
|
||||
const ullong * receiveCountPerSec_ptr() const {return &packets_in_sec;}
|
||||
ullong sendCountPerSec() const {return packets_out_sec;}
|
||||
const ullong * sendCountPerSec_ptr() const {return &packets_out_sec;}
|
||||
ullong receiveBytesPerSec() const {return bytes_in_sec;}
|
||||
const ullong * receiveBytesPerSec_ptr() const {return &bytes_in_sec;}
|
||||
ullong sendBytesPerSec() const {return bytes_out_sec;}
|
||||
const ullong * sendBytesPerSec_ptr() const {return &bytes_out_sec;}
|
||||
ullong receiveCount() const {return receive_count;}
|
||||
const ullong * receiveCount_ptr() const {return &receive_count;}
|
||||
ullong wrongCount() const {return wrong_count;}
|
||||
const ullong * wrongCount_ptr() const {return &wrong_count;}
|
||||
ullong sendCount() const {return send_count;}
|
||||
const ullong * sendCount_ptr() const {return &send_count;}
|
||||
ullong missedCount() const {return missed_count;}
|
||||
const ullong * missedCount_ptr() const {return &missed_count;}
|
||||
PIProtocol::Quality quality() const {return net_diag;} // receive quality
|
||||
const int * quality_ptr() const {return (int * )&net_diag;} // receive quality pointer
|
||||
PIString receiverDeviceName() const {return devReceiverName;}
|
||||
PIString senderDeviceName() const {return devSenderName;}
|
||||
PIString receiverDeviceState() const {return devReceiverState;}
|
||||
const PIString * receiverDeviceState_ptr() const {return &devReceiverState;}
|
||||
PIString senderDeviceState() const {return devSenderState;}
|
||||
const PIString * senderDeviceState_ptr() const {return &devSenderState;}
|
||||
PIString receiveSpeed() const {return speedIn;}
|
||||
const PIString * receiveSpeed_ptr() const {return &speedIn;}
|
||||
PIString sendSpeed() const {return speedOut;}
|
||||
const PIString * sendSpeed_ptr() const {return &speedOut;}
|
||||
|
||||
void * receiveData() {return dataPtr;}
|
||||
void * sendData() {return sendDataPtr;}
|
||||
|
||||
PIPacketExtractor * packetExtractor() {return packet_ext;}
|
||||
// PIByteArray lastHeader() {return packet_ext->lastHeader();}
|
||||
|
||||
EVENT0(receiverStarted)
|
||||
EVENT0(receiverStopped)
|
||||
EVENT0(senderStarted)
|
||||
EVENT0(senderStopped)
|
||||
EVENT1(received, bool, validate_is_ok)
|
||||
EVENT2(qualityChanged, PIProtocol::Quality, new_quality, PIProtocol::Quality, old_quality)
|
||||
|
||||
protected:
|
||||
virtual bool receive(uchar * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return
|
||||
virtual bool validate() {return true;} // function for validate algorithm and save data from dataPtr to external struct
|
||||
virtual bool headerValidate(uchar * src, uchar * rec, int size) {for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;} // function for validate header (COM-port and headerSize > 0)
|
||||
virtual uint checksum_i(void * data, int size) { // function for checksum (uint)
|
||||
uint c = 0;
|
||||
for (int i = 0; i < size; ++i)
|
||||
c += ((uchar*)data)[i];
|
||||
return ~(c + 1);
|
||||
}
|
||||
virtual uchar checksum_c(void * data, int size) { // function for checksum (uchar)
|
||||
uchar c = 0;
|
||||
for (int i = 0; i < size; ++i)
|
||||
c += ((uchar*)data)[i];
|
||||
return ~(c + 1);
|
||||
}
|
||||
virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending
|
||||
|
||||
void init();
|
||||
void init_sender(PIConfig::Entry & b, PIConfig::Entry & sb, const PIString & config);
|
||||
void init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const PIString & config);
|
||||
void check_state();
|
||||
void calc_freq();
|
||||
void calc_diag();
|
||||
|
||||
PISerial * ser;
|
||||
PIEthernet * eth;
|
||||
uint dataSize, headerSize, sendDataSize;
|
||||
uchar * dataPtr, * headerPtr, * sendDataPtr;
|
||||
|
||||
private:
|
||||
static void sendEvent(void * e, int) {((PIProtocol * )e)->send();}
|
||||
static bool receiveEvent(void * t, uchar * data, int size);
|
||||
static bool headerValidateEvent(void * t, uchar * src, uchar * rec, int size) {return ((PIProtocol * )t)->headerValidate(src, rec, size);}
|
||||
static void diagEvent(void * t, int);
|
||||
static void secEvent(void * t, int);
|
||||
|
||||
void setMultiProtocolOwner(PIMultiProtocolBase * mp) {mp_owner = mp;}
|
||||
PIMultiProtocolBase * multiProtocolOwner() const {return mp_owner;}
|
||||
void changeDisconnectTimeout();
|
||||
|
||||
ReceiveFunc ret_func;
|
||||
PIPacketExtractor * packet_ext;
|
||||
PITimer * diagTimer, * sendTimer, * secTimer;
|
||||
PITimeMeasurer diag_tm;
|
||||
PIMultiProtocolBase * mp_owner;
|
||||
PIProtocol::Type type_send, type_rec;
|
||||
PIProtocol::Quality net_diag;
|
||||
PIDeque<float> last_freq;
|
||||
PIDeque<char> last_packets;
|
||||
PIString protName, devReceiverName, devReceiverState, devSenderName, devSenderState, speedIn, speedOut;
|
||||
bool work, new_mp_prot;
|
||||
float exp_freq, send_freq, ifreq, immediate_freq, integral_freq, timeout_;
|
||||
int packets[2], pckt_cnt, pckt_cnt_max;
|
||||
char cur_pckt;
|
||||
ullong wrong_count, receive_count, send_count, missed_count, packets_in_sec, packets_out_sec, bytes_in_sec, bytes_out_sec;
|
||||
|
||||
};
|
||||
|
||||
#endif // PIPROTOCOL_H
|
||||