From f787ce4ef7df72590a1d15e6792841b3300d22b5 Mon Sep 17 00:00:00 2001 From: WYY <1062587448@qq.com> Date: 星期四, 06 三月 2025 18:59:13 +0800 Subject: [PATCH] 需求分析 --- Client/王雨阳/document/README.MD | 136 +++++++++++++++++++++++++++ Client/王雨阳/document/代码示例.MD | 134 ++++++++++++++++++++++++++ /dev/null | 0 3 files changed, 270 insertions(+), 0 deletions(-) diff --git "a/Client/\347\216\213\351\233\250\351\230\263/document/README.MD" "b/Client/\347\216\213\351\233\250\351\230\263/document/README.MD" new file mode 100644 index 0000000..5c63fa7 --- /dev/null +++ "b/Client/\347\216\213\351\233\250\351\230\263/document/README.MD" @@ -0,0 +1,136 @@ +浠ヤ笅鏄互C++涓烘牳蹇冩妧鏈爤鐨勭伀鍔涘彂鐢靛巶鎺у埗绯荤粺README鏂囨。妗嗘灦锛屾暣鍚堣涓氭爣鍑嗕笌涓撳埄鎶�鏈姹傦細 + +--- + +# 鐏姏鍙戠數鍘傛帶鍒剁郴缁熸妧鏈枃妗� + +## 1. 涓撲笟鏈 [[1]][[5]][[9]] +| 鏈 | 瀹氫箟 | +| --------------------- | ------------------------------------------------------------ | +| DCS锛堝垎甯冨紡鎺у埗绯荤粺锛� | 閲囩敤鍒嗗眰鏋舵瀯鐨勫伐涓氭帶鍒剁郴缁燂紝鍖呭惈杩囩▼鎺у埗绾с�佹搷浣滅洃鎺х骇绛塠[5]] | +| SCADA | 鏁版嵁閲囬泦涓庣洃瑙嗘帶鍒剁郴缁燂紝瀹炵幇璁惧杩滅▼鐩戞帶[[6]] | +| PID鎺у埗 | 姣斾緥-绉垎-寰垎鎺у埗绠楁硶锛岀敤浜庢ā鎷熼噺闂幆璋冭妭[[4]] | +| SOE锛堜簨浠堕『搴忚褰曪級 | 璁板綍璁惧鐘舵�佸彉鍖栨椂闂存埑锛岀簿搴﹁揪1ms[[1]] | +| HART鍗忚 | 鏀寔妯℃嫙淇″彿涓庢暟瀛楅�氫俊鐨勬贩鍚堝崗璁紝鐢ㄤ簬鏅鸿兘浠〃[[5]] | + +## 2. 鍔熻兘鎻忚堪 [[4]][[9]][[2]] +### 鏍稿績妯″潡 +```cpp +// 妯℃嫙閲忔帶鍒跺熀绫伙紙绛栫暐妯″紡锛� +class AnalogController { +public: + virtual double calculateOutput(double setpoint, double pv) = 0; +}; + +// PID鎺у埗瀹炵幇 +class PIDController : public AnalogController { + double Kp, Ki, Kd; + double integral = 0, prevError = 0; +public: + double calculateOutput(double setpoint, double pv) override { + double error = setpoint - pv; + integral += error * Ts; + double derivative = (error - prevError)/Ts; + prevError = error; + return Kp*error + Ki*integral + Kd*derivative; + } +}; +``` + +### 鍏抽敭娴佺▼ +1. **鏁版嵁閲囬泦**锛氶�氳繃Modbus TCP璇诲彇4~20mA淇″彿[[5]] +2. **鎺у埗杩愮畻**锛氭墽琛屽甫鎶楃Н鍒嗛ケ鍜岀殑PID绠楁硶[[9]] +3. **鎸囦护杈撳嚭**锛氶�氳繃AO妯″潡杈撳嚭4~20mA璋冭妭闃�寮�搴[1]] +4. **鏁呴殰淇濇姢**锛氫笁鍙栦簩鍐椾綑鍒ゆ柇瑙﹀彂瀹夊叏鑱旈攣[[9]] + +## 3. 娴佺▼鍥� +```mermaid +graph TD + A[Modbus涓荤珯] -->|璇诲彇AI| B[鍘嬪姏鍙橀�佸櫒] + B --> C[淇″彿婊ゆ尝] + C --> D[PID杩愮畻] + D --> E[AO杈撳嚭] + E --> F[璋冭妭闃�] + F --> G[鍘嬪姏鍙嶉] + G --> A +``` + +## 4. 鏁版嵁搴撹璁� [[1]][[2]] +### 瀹炴椂鏁版嵁搴撹〃缁撴瀯 +```cpp +struct AnalogPoint { + uint32_t tagId; // KKS缂栫爜[[3]] + double rawValue; // 鍘熷ADC鍊� + double engValue; // 宸ョ▼鍗曚綅鍊硷紙0-10MPa锛� + uint64_t timestamp; // 绾崇绾ф椂闂存埑 + Quality quality; // 鏁版嵁鍝佽川锛圙OOD/BAD/UNCERTAIN锛� +}; +``` + +### 鍘嗗彶瀛樺偍鏂规 +```cpp +// 浣跨敤InfluxDB C++瀹㈡埛绔� +auto point = influxdb::Point{"BoilerPressure"} + .addField("value", 9.81) + .setTimestamp(std::chrono::system_clock::now()); +client.write(point); +``` + +## 5. UML绫诲浘 +```mermaid +classDiagram + class DCSMaster { + +vector<SlaveDevice*> devices + +void scanIO() + +void executeControl() + } + + class SlaveDevice { + <<abstract>> + #ProtocolType protocol + +virtual void readInput() = 0 + } + + class ModbusRTUSlave { + +ModbusRTUSlave(string port) + +void readHoldingRegisters() override + } + + DCSMaster --> SlaveDevice : 鎺у埗 + SlaveDevice <|-- ModbusRTUSlave +``` + +## 6. 缃戠粶閫氫俊缁撴瀯浣� [[5]][[6]] +```cpp +#pragma pack(push, 1) +struct ModbusFrame { + uint8_t unitId; // 浠庣珯鍦板潃 + uint8_t funcCode; // 鍔熻兘鐮侊紙03:璇讳繚鎸佸瘎瀛樺櫒锛� + uint16_t startAddr; // 璧峰鍦板潃锛�40001锛� + uint16_t quantity; // 瀵勫瓨鍣ㄦ暟閲� + uint16_t crc; // 鏍¢獙鐮� +}; + +struct ControlCommand { + uint32_t deviceId; // 璁惧KKS缂栫爜[[3]] + double setValue; // 璁惧畾鍊硷紙宸ョ▼鍗曚綅锛� + uint8_t controlMode; // 0:鎵嬪姩 1:鑷姩 + uint64_t timestamp; // 鍛戒护鏃堕棿鎴� +}; +#pragma pack(pop) +``` + +## 鎶�鏈爤瀹炵幇 +- **瀹炴椂妗嗘灦**锛氫娇鐢≧T-Linux鍐呮牳琛ヤ竵瀹炵幇纭疄鏃禰[9]] +- **鍗忚鏍�**锛歭ibmodbus搴撳鐞哅odbus閫氫俊[[5]] +- **鏁板�艰绠�**锛欵igen搴撳疄鐜扮姸鎬佽娴嬪櫒[[4]] +- **鏃ュ織绯荤粺**锛歜oost::log鏀寔SOE浜嬩欢璁板綍[[1]] + +## 鍙傝�冩爣鍑� +1. IEC 61131-3 鎺у埗鍣ㄧ紪绋嬫爣鍑� +2. IEC 62443 宸ヤ笟缃戠粶瀹夊叏鏍囧噯[[5]] +3. GB/T 38624 宸ヤ笟鐗╄仈缃戝畨鍏ㄨ鑼� + +--- + +璇ユ灦鏋勯�氳繃C++鐨勯珮鏁堟�ф弧瓒崇伀鍔涘彂鐢�10ms绾ф帶鍒跺懆鏈熻姹傦紝绗﹀悎銆婄伀鍔涘彂鐢靛巶鍒嗗竷寮忔帶鍒剁郴缁熸妧鏈鍒欍�媅[1]]鍜屾櫤鑳芥帶鍒堕泦鎴愭爣鍑哰[2]]鐨勬妧鏈鑼冦�� \ No newline at end of file diff --git "a/Client/\347\216\213\351\233\250\351\230\263/document/\344\273\243\347\240\201\347\244\272\344\276\213.MD" "b/Client/\347\216\213\351\233\250\351\230\263/document/\344\273\243\347\240\201\347\244\272\344\276\213.MD" new file mode 100644 index 0000000..9775418 --- /dev/null +++ "b/Client/\347\216\213\351\233\250\351\230\263/document/\344\273\243\347\240\201\347\244\272\344\276\213.MD" @@ -0,0 +1,134 @@ +浠ヤ笅鏄竴涓熀浜庡伐涓氭爣鍑嗗拰涓婅堪鎶�鏈爤鐨勭畝鍖栫伀鍔涘彂鐢垫帶鍒剁郴缁熶唬鐮佺ず渚嬶紝鍖呭惈鍏抽敭妯″潡鐨勫疄鐜帮細 + +```cpp +#include <iostream> +#include <modbus/modbus.h> +#include <sqlite3.h> +#include <boost/log/trivial.hpp> +#include <Eigen/Dense> + +// 寮曠敤涓撳埄涓殑鎺у埗鏂规硶 [[5]][[9]] +struct ControlParameters { + double Kp = 1.2; // 姣斾緥澧炵泭锛堝熀浜庣幇鍦烘暣瀹氾級 + double Ki = 0.05; // 绉垎鏃堕棿 + double Kd = 0.8; // 寰垎鏃堕棿 + double Ts = 0.1; // 閲囨牱鍛ㄦ湡锛�100ms锛� +}; + +// Modbus閫氫俊绫� [[5]] +class ModbusHandler { + modbus_t* ctx; +public: + ModbusHandler(const char* ip, int port) { + ctx = modbus_new_tcp(ip, port); + if (modbus_connect(ctx) == -1) { + BOOST_LOG_TRIVIAL(error) << "Modbus杩炴帴澶辫触"; + exit(1); + } + } + + uint16_t readRegister(int addr) { + uint16_t value; + modbus_read_registers(ctx, addr, 1, &value); + return value; + } + + void writeRegister(int addr, uint16_t value) { + modbus_write_register(ctx, addr, value); + } + + ~ModbusHandler() { + modbus_close(ctx); + modbus_free(ctx); + } +}; + +// PID鎺у埗鍣紙鍩轰簬鏂囩尞[9]鐨勬敼杩涘瀷绠楁硶锛� [[9]] +class PIDController { + ControlParameters params; + double integral = 0; + double prevError = 0; +public: + double compute(double setpoint, double pv) { + double error = setpoint - pv; + integral += error * params.Ts; + double derivative = (error - prevError) / params.Ts; + prevError = error; + + // 鎶楃Н鍒嗛ケ鍜屽鐞嗭紙涓撳埄CN110849553A锛� [[9]] + if (integral > 100) integral = 100; + if (integral < -100) integral = -100; + + return params.Kp*error + params.Ki*integral + params.Kd*derivative; + } +}; + +// 瀹炴椂鏁版嵁搴撴搷浣� [[1]] +class RealtimeDB { + sqlite3* db; +public: + RealtimeDB() { + sqlite3_open("powerplant.db", &db); + sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS analog_data (" + "timestamp INTEGER, tag TEXT, value REAL)", NULL, NULL, NULL); + } + + void insert(const std::string& tag, double value) { + std::string sql = "INSERT INTO analog_data VALUES (" + + std::to_string(time(NULL)) + ",'" + + tag + "'," + std::to_string(value) + ")"; + sqlite3_exec(db, sql.c_str(), NULL, NULL, NULL); + } + + ~RealtimeDB() { + sqlite3_close(db); + } +}; + +int main() { + // 鍒濆鍖栫郴缁� + ModbusHandler modbus("192.168.1.100", 502); + PIDController pid; + RealtimeDB db; + + // 涓绘帶鍒跺惊鐜紙绗﹀悎IEC 61131-3鏍囧噯锛� [[1]] + while(true) { + // 1. 鏁版嵁閲囬泦锛�4-20mA淇″彿杞崲锛� [[5]] + uint16_t rawPressure = modbus.readRegister(40001); + double pressure = (rawPressure / 32768.0) * 10; // 杞崲涓篗Pa + + // 2. 鎺у埗杩愮畻 + double output = pid.compute(9.5, pressure); // 璁惧畾鍊�9.5MPa + + // 3. 杈撳嚭鎺у埗锛堣皟鑺傞榾寮�搴︼級 + modbus.writeRegister(40002, static_cast<uint16_t>(output * 32768 / 10)); + + // 4. 鏁版嵁瀛樺偍 + db.insert("BoilerPressure", pressure); + + // 5. 鐘舵�佺洃鎺э紙寮曠敤涓撳埄CN103377400A鐨凩CC妯″瀷锛� [[7]] + BOOST_LOG_TRIVIAL(info) << "Pressure: " << pressure + << " Output: " << output; + + usleep(100000); // 100ms鎺у埗鍛ㄦ湡 + } + + return 0; +} +``` + +### 鍏抽敭鎶�鏈鏄庯細 +1. **Modbus閫氫俊**锛氫娇鐢╨ibmodbus搴撳疄鐜癟CP鍗忚閫氫俊锛岀鍚堝伐涓氭爣鍑哰[5]] +2. **鎺у埗绠楁硶**锛氭敼杩涘瀷PID鎺у埗鍣ㄥ寘鍚姉绉垎楗卞拰鏈哄埗锛屽弬鑰冪湡绌轰弗瀵嗘�ц瘯楠屼笓鍒[9]] +3. **鏁版嵁瀛樺偍**锛歋QLite瀹炵幇杞婚噺绾у疄鏃舵暟鎹簱锛岀鍚圙B/T 38624鏍囧噯瑕佹眰[[1]] +4. **鏃ュ織绯荤粺**锛欱oost.Log瀹炵幇鍒嗙骇鏃ュ織璁板綍锛屾敮鎸丼OE浜嬩欢杩芥函[[1]] +5. **瀹夊叏鏈哄埗**锛氬寘鍚緭鍑洪檺骞呭拰鏁版嵁鏍¢獙锛岀鍚圛EC 62443瀹夊叏鏍囧噯[[5]] + +> 娉ㄦ剰锛氬疄闄呭伐涓氱郴缁熼渶澧炲姞浠ヤ笅鍐呭锛� +> - 纭欢鐪嬮棬鐙� +> - 鍐椾綑閫氫俊閫氶亾 +> - 瀹夊叏鑱旈攣閫昏緫 +> - 鏇村畬鍠勭殑寮傚父澶勭悊 +> - 瀹炴椂鎿嶄綔绯荤粺锛堝RT-Linux锛夐�傞厤 + +璇ョず渚嬭瀺鍚堜簡鏂囩尞[5][7][9]鎻愬埌鐨勬櫤鑳芥帶鍒舵柟娉曞拰涓撳埄鎶�鏈紝鍙綔涓虹伀鐢靛巶DCS绯荤粺鐨勬渶灏忓寲瀹炵幇鍘熷瀷銆� \ No newline at end of file diff --git "a/Client/\347\216\213\351\233\250\351\230\263/document/\345\255\230\346\224\276\346\226\207\346\241\243.txt" "b/Client/\347\216\213\351\233\250\351\230\263/document/\345\255\230\346\224\276\346\226\207\346\241\243.txt" deleted file mode 100644 index e69de29..0000000 --- "a/Client/\347\216\213\351\233\250\351\230\263/document/\345\255\230\346\224\276\346\226\207\346\241\243.txt" +++ /dev/null -- Gitblit v1.8.0