diff --git a/modules/modules.pro b/modules/modules.pro
index c8c68236ba654aab252708d8260bc626da6b2020..ae722888bf473a98b3c6e1ffb59ea084d07feb35 100644
--- a/modules/modules.pro
+++ b/modules/modules.pro
@@ -5,6 +5,7 @@ SUBDIRS += \
sources/source_plutosdr \
transforms/transform_fft \
transforms/mod_fm \
+ transforms/mod_fm_dem \
transforms/filter_fir \
transforms/resample_pqfraction \
sources/source_files \
diff --git a/modules/sinks/sink_soundcard/dialogsoundcard.ui b/modules/sinks/sink_soundcard/dialogsoundcard.ui
index 976c80d551f2d891d6c06f932664974d05ba43a9..0d2daa245780d4870d436d2f3cbbd371b9ba4f9e 100644
--- a/modules/sinks/sink_soundcard/dialogsoundcard.ui
+++ b/modules/sinks/sink_soundcard/dialogsoundcard.ui
@@ -7,7 +7,7 @@
0
0
306
- 154
+ 182
@@ -43,10 +43,10 @@
4000
- 192000
+ 500000
- 48000
+ 44100
@@ -66,7 +66,7 @@
5
- 2
+ 1
diff --git a/modules/sources/source_soundcard/dialogsoundcard.ui b/modules/sources/source_soundcard/dialogsoundcard.ui
index 976c80d551f2d891d6c06f932664974d05ba43a9..0d2daa245780d4870d436d2f3cbbd371b9ba4f9e 100644
--- a/modules/sources/source_soundcard/dialogsoundcard.ui
+++ b/modules/sources/source_soundcard/dialogsoundcard.ui
@@ -7,7 +7,7 @@
0
0
306
- 154
+ 182
@@ -43,10 +43,10 @@
4000
- 192000
+ 500000
- 48000
+ 44100
@@ -66,7 +66,7 @@
5
- 2
+ 1
diff --git a/modules/transforms/CMakeLists.txt b/modules/transforms/CMakeLists.txt
index 6e95ca32eb824c98462c3df65ff1467b2cbdd553..90a0646dbab12b7b3fd8e94966f2b30ea0c45121 100644
--- a/modules/transforms/CMakeLists.txt
+++ b/modules/transforms/CMakeLists.txt
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.5)
add_subdirectory(mod_fm)
+add_subdirectory(mod_fm_dem)
add_subdirectory(transform_fft)
add_subdirectory(filter_fir)
add_subdirectory(resample_pqfraction)
diff --git a/modules/transforms/mod_fm_dem/CMakeLists.txt b/modules/transforms/mod_fm_dem/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..33ff250b0f0a86c05f9077996a179ce15ab3d8da
--- /dev/null
+++ b/modules/transforms/mod_fm_dem/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 3.5)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)
+find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
+include_directories(${TASKBUS_INTERFACEDIR})
+set(PRJ_SOURCES
+ main.cpp
+ info.qrc
+)
+#############Target======================
+
+add_executable(mod_fm_dem
+ ${PRJ_SOURCES}
+)
+target_link_libraries(mod_fm_dem Qt${QT_VERSION_MAJOR}::Core)
+
diff --git a/modules/transforms/mod_fm_dem/info.qrc b/modules/transforms/mod_fm_dem/info.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..5d86910df89a1319074565b39b48d521703d10ee
--- /dev/null
+++ b/modules/transforms/mod_fm_dem/info.qrc
@@ -0,0 +1,5 @@
+
+
+ mod_fm_dem.json
+
+
diff --git a/modules/transforms/mod_fm_dem/main.cpp b/modules/transforms/mod_fm_dem/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fcc19a5502e2753412ff03e1c8e717f9828c6788
--- /dev/null
+++ b/modules/transforms/mod_fm_dem/main.cpp
@@ -0,0 +1,166 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "cmdlineparser.h"
+#include "tb_interface.h"
+using namespace TASKBUS;
+const int OFFLINEDEBUG = 0;
+//数据源方法
+int do_mod_fm_dem(const cmdlineParser & args);
+//全局的终止标记
+static bool bfinished = false;
+using namespace std;
+int main(int argc , char * argv[])
+{
+ QCoreApplication a(argc, argv);
+ //重要!设置输入输出为二进制!
+ init_client();
+
+ //解释命令行
+ cmdlineParser args;
+ if (OFFLINEDEBUG==0)
+ args.parser(argc,argv);
+ else
+ {
+ FILE * old_stdin, *old_stdout;
+ auto ars = debug("/home/goldenhawking/projects/taskbus/bin_linux_64/bin/debug/pid4113",&old_stdin,&old_stdout);
+ args.parser(ars);
+ }
+
+ int ret = 0;
+ //每个模块要响应 --information参数,打印自己的功能定义字符串。或者提供一个json文件。
+ if (args.contains("information"))
+ {
+ QFile fp(":/mod_fm_dem.json");
+ fp.open(QIODevice::ReadOnly);
+ if (fp.isOpen())
+ {
+ QByteArray arr = fp.readAll();
+ arr.push_back('\0');
+ puts(arr.constData());
+ fflush(stdout);
+ }
+
+ return 0;
+ }
+ else if (args.contains("function"/*,"mod_fm"*/))//正常运行模式
+ {
+ ret = do_mod_fm_dem(args);
+ }
+ else
+ {
+ fprintf(stderr,"Error:Function does not exits.");
+ ret = -1;
+ }
+
+ return ret;
+}
+
+#define Pi 3.14159265354
+int do_mod_fm_dem(const cmdlineParser & args)
+{
+ using namespace TASKBUS;
+ int res = 0;
+ //获得平台告诉自己的实例名
+ const unsigned int instance = args.toInt("instance",0);
+ const unsigned int itmstamp_in = args.toUInt("tmstamp_in",0);
+ const unsigned int itmstamp_out = args.toUInt("tmstamp_out",0);
+ const unsigned int isig = args.toInt("signal",0);
+ const unsigned int osound = args.toInt("sound",0);
+ //工作模式
+ try{
+ //判断参数合法性
+ if (instance==0)
+ throw "function=quit;{\"error\":\"instance is 0, quit.\"}";
+ int failed_header = 0;
+ int last_i = 0, last_q = 0;
+ while (false==bfinished)
+ {
+ subject_package_header header;
+ vector packagedta = pull_subject(&header);
+ if (is_valid_header(header)==false)
+ {
+ if (++failed_header>16)
+ bfinished = true;
+ continue;
+ }
+ if ( is_control_subject(header))
+ {
+ //收到命令进程退出的广播消息,退出
+ if (strstr(control_subject(header,packagedta).c_str(),"function=quit;")!=nullptr)
+ bfinished = true;
+ }
+ else if (header.subject_id==itmstamp_in)
+ {
+ const unsigned char * pdta = (unsigned char *) packagedta.data();
+ if (itmstamp_out)
+ {
+ push_subject(itmstamp_out,instance,packagedta.size(),
+ pdta
+ );
+ }
+ }
+ else if (header.subject_id == isig)
+ {
+ std::vector vec_output;
+
+ const unsigned char * pdta = packagedta.data();
+ const int nPts = header.data_length / sizeof(short)/2;
+ const short (* pdata)[2] = (const short (*)[2])pdta;
+ for (int j=0;j0)? Pi/2:-Pi/2;
+ else if (diff_i >0 )
+ angle = atan(diff_q*1.0/diff_i);
+ else if (diff_q >=0)
+ angle = atan(diff_q*1.0/diff_i)+Pi;
+ else
+ angle = atan(diff_q*1.0/diff_i)-Pi;
+
+ last_i = curr_i;
+ last_q = curr_q;
+
+ vec_output.push_back(angle/Pi*4096);
+
+ }
+ //播发
+ if (osound)
+ {
+ push_subject(osound,instance,vec_output.size()*2,
+ (unsigned char *)vec_output.data()
+ );
+ }
+
+
+ }
+ }
+
+
+ }
+ catch (const char * errMessage)
+ {
+ //向所有部位广播,偶要退出。
+ push_subject(control_subect_id(),/*instance,broadcast_destin_id(),*/0,errMessage);
+ fprintf(stderr,"Error:%s.",errMessage);
+ fflush (stderr);
+ res = -1;
+ }
+
+ return res;
+}
+
diff --git a/modules/transforms/mod_fm_dem/mod_fm_dem.json b/modules/transforms/mod_fm_dem/mod_fm_dem.json
new file mode 100644
index 0000000000000000000000000000000000000000..531a7838186b55a9809e7be6f3ced45ff056c67b
--- /dev/null
+++ b/modules/transforms/mod_fm_dem/mod_fm_dem.json
@@ -0,0 +1,29 @@
+{
+ "mod_fm_dem":{
+ "name":"fm_dem",
+ "parameters":{
+ },
+ "input_subjects":
+ {
+ "signal":{
+ "type":"vector",
+ "tooltip":"fm signal"
+ },
+ "tmstamp_in":{
+ "type":"unsigned long long",
+ "tooltip":"tmstamp_in"
+ }
+ },
+ "output_subjects":{
+ "sound":{
+ "type":"byte",
+ "tooltip":"sound"
+ },
+ "tmstamp_out":{
+ "type":"unsigned long long",
+ "tooltip":"tmstamp_out"
+ }
+
+ }
+ }
+}
diff --git a/modules/transforms/mod_fm_dem/mod_fm_dem.pro b/modules/transforms/mod_fm_dem/mod_fm_dem.pro
new file mode 100644
index 0000000000000000000000000000000000000000..fa46de0a8c99bfd5f7f5d642b313027486d32dd2
--- /dev/null
+++ b/modules/transforms/mod_fm_dem/mod_fm_dem.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+QT -= gui
+CONFIG += c++11 console
+CONFIG -= app_bundle
+INCLUDEPATH += ../../../tb_interface
+DESTDIR = $$OUT_PWD/../../../bin/modules
+SOURCES += \
+ main.cpp
+
+RESOURCES += \
+ info.qrc
\ No newline at end of file
diff --git a/projects/usrp_fmradio.tbj b/projects/usrp_fm_emitter.tbj
similarity index 100%
rename from projects/usrp_fmradio.tbj
rename to projects/usrp_fm_emitter.tbj
diff --git a/projects/usrp_fm_reciever.tbj b/projects/usrp_fm_reciever.tbj
new file mode 100644
index 0000000000000000000000000000000000000000..5438fb00a5a1e426b313f5273e2822ad7cd23e6b
--- /dev/null
+++ b/projects/usrp_fm_reciever.tbj
@@ -0,0 +1,554 @@
+{
+ "mod0": {
+ "uhd_usrp_io": {
+ "input_subjects": {
+ "tx_time": {
+ "instance_value": "",
+ "tooltip": "tx_time",
+ "type": "uint64+double"
+ },
+ "wav_tx0": {
+ "instance_value": "",
+ "tooltip": "TX0",
+ "type": "short[2]"
+ },
+ "wav_tx1": {
+ "instance_value": "",
+ "tooltip": "TX1",
+ "type": "short[2]"
+ }
+ },
+ "instance": {
+ "additional_args": "nice=0;",
+ "exec": "modules/uhd_usrp_io",
+ "instance_value": 1
+ },
+ "name": {
+ "name": "UHD收发"
+ },
+ "output_subjects": {
+ "rx_time": {
+ "instance_value": 0,
+ "tooltip": "rx_time",
+ "type": "uint64+double"
+ },
+ "wav_rx0": {
+ "instance_value": 3,
+ "tooltip": "RX0",
+ "type": "short[2]"
+ },
+ "wav_rx1": {
+ "instance_value": "",
+ "tooltip": "RX1",
+ "type": "short[2]"
+ }
+ },
+ "parameters": {
+ "dev_args": {
+ "default": "",
+ "instance_value": "",
+ "tooltip": "设备初始化参数.",
+ "type": "string"
+ },
+ "rx_agc": {
+ "default": "0,0",
+ "instance_value": "0,0",
+ "range": "0=off,1=on",
+ "tooltip": "接收AGC开关",
+ "type": "int"
+ },
+ "rx_atn": {
+ "default": "RX2,RX2",
+ "instance_value": "RX2",
+ "range": "TX/RX,RX2",
+ "tooltip": "接收天线名称",
+ "type": "string"
+ },
+ "rx_bw": {
+ "default": "1.0,1.0",
+ "instance_value": "0.2,0.2",
+ "tooltip": "接收滤波器带宽(MHz)",
+ "type": "double"
+ },
+ "rx_channels": {
+ "default": "0,1",
+ "instance_value": "0",
+ "range": "0,1",
+ "tooltip": "接收各个通道号",
+ "type": "int"
+ },
+ "rx_gain": {
+ "default": "30.0,30.0",
+ "instance_value": "50",
+ "range": "0-100",
+ "tooltip": "接收增益(dB)",
+ "type": "double"
+ },
+ "rx_on": {
+ "default": "0",
+ "instance_value": "1",
+ "tooltip": "接收开关",
+ "type": "int"
+ },
+ "rx_rate": {
+ "default": 1,
+ "instance_value": "0.5",
+ "tooltip": "RX采样率(MHz)",
+ "type": "int"
+ },
+ "rx_rf": {
+ "default": "99.0,101.1",
+ "instance_value": "99.0",
+ "range": "0-6000",
+ "tooltip": "接收频率(MHz)",
+ "type": "double"
+ },
+ "tx_atn": {
+ "default": "TX/RX,TX/RX",
+ "instance_value": "TX/RX,TX/RX",
+ "tooltip": "发射天线名称",
+ "type": "string"
+ },
+ "tx_bw": {
+ "default": "1.0,1.0",
+ "instance_value": "1.0,1.0",
+ "tooltip": "发射滤波器带宽(MHz)",
+ "type": "double"
+ },
+ "tx_channels": {
+ "default": "0,1",
+ "instance_value": "0,1",
+ "tooltip": "发射各个通道",
+ "type": "int"
+ },
+ "tx_gain": {
+ "default": "30.0,30.0",
+ "instance_value": "30.0,30.0",
+ "range": "0-100",
+ "tooltip": "发射增益(dB)",
+ "type": "double"
+ },
+ "tx_on": {
+ "default": 0,
+ "instance_value": 0,
+ "tooltip": "发射开关",
+ "type": "int"
+ },
+ "tx_rate": {
+ "default": 1,
+ "instance_value": 1,
+ "tooltip": "TX采样率(MHz)",
+ "type": "int"
+ },
+ "tx_rf": {
+ "default": "200.0,203.0",
+ "instance_value": "200.0,203.0",
+ "range": "0-6000",
+ "tooltip": "发射频率(MHz)",
+ "type": "double"
+ }
+ }
+ }
+ },
+ "mod1": {
+ "transform_fft": {
+ "input_subjects": {
+ "signal": {
+ "instance_value": 8,
+ "tooltip": "signal",
+ "type": "byte"
+ },
+ "tmstamp_in": {
+ "instance_value": 0,
+ "tooltip": "tmstamp_in",
+ "type": "uint64"
+ }
+ },
+ "instance": {
+ "additional_args": "nice=0;",
+ "exec": "modules/transform_fft",
+ "instance_value": 2
+ },
+ "name": {
+ "name": "libfftw"
+ },
+ "output_subjects": {
+ "FFT": {
+ "instance_value": 4,
+ "tooltip": "FFT in dB",
+ "type": "vector"
+ },
+ "Spec": {
+ "instance_value": "",
+ "tooltip": "Spec in Complex",
+ "type": "vector"
+ },
+ "tmstamp_out": {
+ "instance_value": 0,
+ "tooltip": "tmstamp_out",
+ "type": "uint64"
+ }
+ },
+ "parameters": {
+ "channels": {
+ "default": 1,
+ "instance_value": 1,
+ "tooltip": "Channels",
+ "type": "int"
+ },
+ "fftsize": {
+ "default": 1024,
+ "instance_value": 1024,
+ "tooltip": "fft size",
+ "type": "int"
+ },
+ "input_type": {
+ "default": 0,
+ "instance_value": "1",
+ "tooltip": "0=Real,1=Complex",
+ "type": "int"
+ },
+ "sptype": {
+ "default": 0,
+ "instance_value": 0,
+ "range": {
+ "0": "16 bit Intel",
+ "1": "16 bit Moto",
+ "2": "int8",
+ "3": "uint8"
+ },
+ "tooltip": "sample point format",
+ "type": "enum"
+ }
+ }
+ }
+ },
+ "mod2": {
+ "sink_plots": {
+ "input_subjects": {
+ "plot0": {
+ "instance_value": 9,
+ "tooltip": "input0",
+ "type": "byte"
+ },
+ "plot1": {
+ "instance_value": 4,
+ "tooltip": "input1",
+ "type": "byte"
+ },
+ "plot2": {
+ "instance_value": "",
+ "tooltip": "input2",
+ "type": "byte"
+ },
+ "plot3": {
+ "instance_value": "",
+ "tooltip": "input3",
+ "type": "byte"
+ },
+ "plot4": {
+ "instance_value": "",
+ "tooltip": "input4",
+ "type": "byte"
+ }
+ },
+ "instance": {
+ "additional_args": "nice=0;",
+ "exec": "modules/sink_plots",
+ "instance_value": 3
+ },
+ "name": {
+ "name": "plots"
+ },
+ "parameters": {
+ "channels": {
+ "default": "1,1,1,1,1,1",
+ "instance_value": "0,0",
+ "range": {
+ "tip": "0:1d spectrogram 1: 1d wav or 2:2d xy"
+ },
+ "tooltip": "各路通道数",
+ "type": "string"
+ },
+ "datatypes": {
+ "default": "9,9,9,9,9",
+ "instance_value": "9,9,9,9,9",
+ "range": {
+ "value": "0:uint8 1:int8 2:uint16 3:int16 4:uint32 5:int32 6:uint64 7:int64 8:float 9:double"
+ },
+ "tooltip": "各路数据类型",
+ "type": "string"
+ }
+ },
+ "version": {
+ "version": "1,1,0"
+ }
+ }
+ },
+ "mod3": {
+ "resample_pqfraction": {
+ "input_subjects": {
+ "in": {
+ "instance_value": 3,
+ "tooltip": "Input",
+ "type": "byte"
+ },
+ "in_time": {
+ "instance_value": 1,
+ "tooltip": "Input timestamp",
+ "type": "timestamp"
+ }
+ },
+ "instance": {
+ "additional_args": "nice=0;",
+ "exec": "modules/resample_pqfraction",
+ "instance_value": 4
+ },
+ "name": {
+ "name": "resamplepq"
+ },
+ "output_subjects": {
+ "out": {
+ "instance_value": 8,
+ "tooltip": "Output",
+ "type": "vector"
+ },
+ "out_time": {
+ "instance_value": 0,
+ "tooltip": "Out timestamp",
+ "type": "timestamp"
+ }
+ },
+ "parameters": {
+ "np": {
+ "default": "1",
+ "instance_value": "200",
+ "range": "N",
+ "tooltip": "new rate",
+ "type": "int"
+ },
+ "nq": {
+ "default": "1",
+ "instance_value": "500",
+ "range": "N",
+ "tooltip": "old rate",
+ "type": "int"
+ },
+ "sptype": {
+ "default": 0,
+ "instance_value": 0,
+ "range": {
+ "0": "16 bit Intel",
+ "1": "16 bit Moto",
+ "2": "int8",
+ "3": "uint8"
+ },
+ "tooltip": "sample point format",
+ "type": "enum"
+ },
+ "type": {
+ "default": "1",
+ "instance_value": "1",
+ "range": "0:real,1:complex",
+ "tooltip": "type",
+ "type": "int"
+ }
+ }
+ }
+ },
+ "mod4": {
+ "sink_soundcard": {
+ "input_subjects": {
+ "timestamp_in": {
+ "instance_value": 0,
+ "tooltip": "timestamp ref",
+ "type": "uint64"
+ },
+ "wav": {
+ "instance_value": 5,
+ "tooltip": "Sample Points",
+ "type": "bytes"
+ }
+ },
+ "instance": {
+ "additional_args": "nice=0;",
+ "exec": "modules/sink_soundcard",
+ "instance_value": 5
+ },
+ "name": {
+ "name": "soundcard"
+ },
+ "parameters": {
+ "autostart": {
+ "default": 0,
+ "instance_value": "1",
+ "tooltip": "auto start",
+ "type": "int"
+ },
+ "channel": {
+ "default": 2,
+ "instance_value": "1",
+ "tooltip": "channels",
+ "type": "int"
+ },
+ "device": {
+ "default": "default",
+ "instance_value": "default",
+ "tooltip": "device name",
+ "type": "string"
+ },
+ "hide": {
+ "default": 0,
+ "instance_value": 0,
+ "tooltip": "hide window when start",
+ "type": "int"
+ },
+ "sample_rate": {
+ "default": 44100,
+ "instance_value": "32000",
+ "range": {
+ "desc": "8000~192000"
+ },
+ "tooltip": "sample rate (Hz)",
+ "type": "int"
+ }
+ }
+ }
+ },
+ "mod5": {
+ "mod_fm_dem": {
+ "input_subjects": {
+ "signal": {
+ "instance_value": 8,
+ "tooltip": "fm signal",
+ "type": "vector"
+ },
+ "tmstamp_in": {
+ "instance_value": 0,
+ "tooltip": "tmstamp_in",
+ "type": "unsigned long long"
+ }
+ },
+ "instance": {
+ "additional_args": "nice=0;",
+ "exec": "modules/mod_fm_dem",
+ "instance_value": 6
+ },
+ "name": {
+ "name": "fm_dem"
+ },
+ "output_subjects": {
+ "sound": {
+ "instance_value": 2,
+ "tooltip": "sound",
+ "type": "byte"
+ },
+ "tmstamp_out": {
+ "instance_value": 0,
+ "tooltip": "tmstamp_out",
+ "type": "unsigned long long"
+ }
+ }
+ }
+ },
+ "mod6": {
+ "resample_pqfraction": {
+ "input_subjects": {
+ "in": {
+ "instance_value": 2,
+ "tooltip": "Input",
+ "type": "byte"
+ },
+ "in_time": {
+ "instance_value": "",
+ "tooltip": "Input timestamp",
+ "type": "timestamp"
+ }
+ },
+ "instance": {
+ "additional_args": "nice=0;",
+ "exec": "modules/resample_pqfraction",
+ "instance_value": 7
+ },
+ "name": {
+ "name": "resamplepq"
+ },
+ "output_subjects": {
+ "out": {
+ "instance_value": 5,
+ "tooltip": "Output",
+ "type": "vector"
+ },
+ "out_time": {
+ "instance_value": "",
+ "tooltip": "Out timestamp",
+ "type": "timestamp"
+ }
+ },
+ "parameters": {
+ "np": {
+ "default": "1",
+ "instance_value": "32000",
+ "range": "N",
+ "tooltip": "new rate",
+ "type": "int"
+ },
+ "nq": {
+ "default": "1",
+ "instance_value": "200000",
+ "range": "N",
+ "tooltip": "old rate",
+ "type": "int"
+ },
+ "sptype": {
+ "default": 0,
+ "instance_value": 0,
+ "range": {
+ "0": "16 bit Intel",
+ "1": "16 bit Moto",
+ "2": "int8",
+ "3": "uint8"
+ },
+ "tooltip": "sample point format",
+ "type": "enum"
+ },
+ "type": {
+ "default": "1",
+ "instance_value": "1",
+ "range": "0:real,1:complex",
+ "tooltip": "type",
+ "type": "int"
+ }
+ }
+ }
+ },
+ "pos0": {
+ "x": 1519,
+ "y": 1375
+ },
+ "pos1": {
+ "x": 2078,
+ "y": 1340
+ },
+ "pos2": {
+ "x": 2383,
+ "y": 1327
+ },
+ "pos3": {
+ "x": 1805,
+ "y": 1467
+ },
+ "pos4": {
+ "x": 2649,
+ "y": 1414
+ },
+ "pos5": {
+ "x": 2085,
+ "y": 1511
+ },
+ "pos6": {
+ "x": 2378,
+ "y": 1518
+ },
+ "total_mods": 7
+}