winprop二次开发

winprop二次开发

  • 前言
  • 工具1——整合多个天线结果
    • 用途
    • 代码实现
  • 工具2——wallman辅助工具
    • 需求
    • 代码实现
      • 功能实现
      • 参数输入
      • 实验

前言

工作需求,对该软件进行简单地二次开发,都是一些挺简单的代码,单纯是为了上传之后将其从本地删除

工具1——整合多个天线结果

用途

winprop最终的计算结果(必选项:接受功率,除此之外可选场强等)是以天线为单位给出热力图,如下图所示:
在这里插入图片描述

某些情况下,这种可视化的方式并不能满足我们的使用需求,比如:在一个实际项目中,我想知道我安装的两台路由器是否能够覆盖整个场景(使每个测试点位接受到的信号强度大于一定阈值),那么彼此独立的热力图并不能简洁地为你提供答案,这就是工具1的用途。
工具1中有一个关键的参数:rule,函数类型:输入是各天线在该测试点位的信号强度。在之前的场景中,我们希望的就是该点收到的信号强度中最强的那个大于阈值,所以我们的规则就是所有信号强度中取最大值。
在这里插入图片描述

代码实现

功能实现:
函数主体: plot_multi_heap_map
参数1:存放run结果的文件路径
参数2:规则(此处规则为平均值)

# ********************************************************************************************
#                                  Author: weixinzhuyi                                       #
#                                  Update: 2024-1-16                                         #
**********************************************************************************************
# a simple tool, but temporarily make up for defects that Winprop can't show us a synthetic image
# if you a better way to overcome the defect, please abandon this script immediately
import re
import os
import matplotlib.pyplot as plt
import numpy as npbase_path = 'D:/Desktop/黑龙江3D/PropName/'# structure full path
def file_name(_site_name, _antenna_name):return base_path + "Site  " + str(_site_name) + " Antenna " + str(_antenna_name) + " Power.txt"# extract information from a file with postfix "Power.txt"
def extract_pro(_file_path):test_point_pattern = re.compile(r'(\d+\.\d+)\s(\d+\.\d+)\s(-\d+\.\d+)')site_location_pattern = re.compile(r'LOCATION\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)')with open(_file_path, "r") as f:content = f.read()_test_point, test_point = re.findall(test_point_pattern, content), list()_site_location, site_location = re.findall(site_location_pattern, content), list()if _test_point:for _ in _test_point:test_point.append(list(map(float, list(_))))site_location = list(map(float, list(_site_location[0])))return site_location, test_point# a interface to plot heatmap of a certain antenna of a certain site(ap)
def plot_single_heap_map(_site_location, _test_point):x, y, power = list(zip(*_test_point))x = set(x)y = set(y)plt.imshow(np.reshape(np.array(power), (len(x), len(y))), cmap=plt.get_cmap('rainbow'))plt.tight_layout()plt.colorbar()plt.show()# get all file names which match name regex
def get_file_path(_path):# if you have a other name system, please change name regex herepattern = re.compile(r'Site\s+\d+ Antenna \d+ Power.txt')ret = list()for _ in os.listdir(_path):if re.findall(pattern, _):ret.append(_path + _)return ret# plot a new heatmap according a certain rule that you offer
# we suppose that a rule you offer a lambda function or a bulit-in function, such as max, min
def plot_multi_heap_map(_path, rule=max):# Calculationfile_dir = get_file_path(_path)site_locations, powers = list(), list()site_location, test_point = extract_pro(file_dir[0])_x, _y, power = list(zip(*test_point))site_locations.append(site_location)x = set(_x)y = set(_y)for file_path in file_dir[1:]:site_location, test_point = extract_pro(file_path)site_locations.append(site_location)_, __, power = list(zip(*test_point))powers.append(power)# Visualizationfinal = list(map(rule, list(zip(*powers))))plt.imshow(np.reshape(np.array(final), (len(x), len(y))), cmap=plt.get_cmap('rainbow'))plt.tight_layout()plt.colorbar()_site_x, _site_y, _ = list(zip(*site_locations))site_x = (np.array(_site_x) - min(x)) * len(x) / (max(x) - min(x))site_y = (np.array(_site_y) - min(y)) * len(y) / (max(y) - min(y))plt.scatter(site_y, site_x)plt.show()if __name__ == '__main__':plot_multi_heap_map(base_path, rule=lambda i: sum(i) / len(i))

工具2——wallman辅助工具

需求

众所周知,使用wallman工具建立三维仿真模型会得到一个**.idb的文件,这个文件可以用feko软件直接打开
在这里插入图片描述
除了保存为idb文件还可以保存为
.ida**二进制文本文件,我们对wallman的开发正是基于这种保存形式,
.ida文件的结构如下:(作者的注释用%%括起来,内容省略使用……)

* Indoor Database *     %数据库类型%
* Last changed on:  2. 1.2024 14: 8:50 *     %最后一次修改时间%BEGIN_MATERIAL     %开始描述3D模型的材料,开头先介绍各种参数(电磁参数、厚度等)对应的位置%
* [MATERIAL]  [ID]  [GENERAL]  ["Name of Material"]  [Thickness (in cm)]   [Filled in Display]   [Color: Red]  [Color: Green]  [Color: Blue]
* [MATERIAL]  [ID]  [FREQUENCY]  [Frequency (in MHz)]  [Dielectrictity (relative)]   [Permeability (relative)]   [Conductivity (in S/m)]  [Transmission Loss Vertical (in dB)]  [Transmission Loss Horizontal (in dB)]  [Reflection Loss (in dB)]  [Diffraction Loss incident min (in dB)]   [Diffraction Loss incident max (in dB)]  [Diffraction Loss diffracted (in dB)]MATERIAL 0 GENERAL "Default Material" 10.00000 1 150 150 150    %该材料只绑定了一个频段2000MHz%
MATERIAL 0 FREQUENCY 2000.000 4.000 1.000 0.010000 10.000 10.000 9.000 8.000 15.000 5.000 20.000 0.100 0.010 0.010 0.100……
END_MATERIAL    %结束对材料的描述%BEGIN_SHAPE    %对形状进行描述, 在保存时选择了compute the shape%
1
1 40 22.050100,89.050100, 5.000000 21.949900,89.050100, 5.000000 21.949900,56.050100, 5.000000 22.050100,89.050100, 5.000000
END_SHAPE    %结束对形状的描述%BEGIN_WALLS   %开始对各类墙体的描述,一个条目代表一面墙,一个正方体对应6个条目%
63     %墙的总数%
%墙的编号    4    x1, y1, z1  x2, y2, z2  x3, y3, z3  x4, y4, z4  材料编号   类型(正常的墙还是有内嵌还是有洞)%
64 4 26.000000,17.000000, 5.000000 26.000000, 8.000000, 5.000000 26.000000, 8.000000, 0.000000 26.000000,17.000000, 0.000000  0 0 
63 4 27.000000,25.000000, 5.000000 27.000000,18.000000, 5.000000 27.000000,18.000000, 0.000000 27.000000,25.000000, 0.000000  0 0 
62 4 27.000000,34.000000, 5.000000 27.000000,28.000000, 5.000000 27.000000,28.000000, 0.000000 27.000000,34.000000, 0.000000  0 0 
……
1 4  5.000000, 0.000000, 0.000000  5.000000, 5.000000, 0.000000  0.000000, 5.000000, 0.000000  0.000000, 0.000000, 0.000000  0 0 
END_WALLS

在了解了ida文件格式后,我们可以通过构造ida文件解决许多繁琐的问题,比如:大量的复杂复制活动
这是一个立方体:
在这里插入图片描述

这是一群立方体:
在这里插入图片描述
或者规模更大
在这里插入图片描述
看起来,我们可以在操作界面通过简单的复制黏贴获得这样的图形,没必要通过构造ida文件的方式。
确实是,对于简单图形来讲,直接复制粘贴更简单,但是一旦遇到了含有嵌入关系或者是由几个基础高度不同的图形拼接起来的整体,往往无法直接复制粘贴。

代码实现

功能实现

可以自由选取墙体批量进行任意位移(增益:gain),比如在上面的例子中,选取的墙体为构成单个正方体的六面墙,位移是 ( x , y , 0 ) , x , y ∈ [ 2 , 4 , 6 , 8 , ⋯ ] (x , y, 0), x,y\in[2, 4, 6, 8,\cdots] (x,y,0),x,y[2,4,6,8,](没有高度的变化,所以第三个分量置为0)

参数输入

  • 入口函数:construct_new_ida_file
  • 输入参数1:位移(增益)(要求为可迭代对象
  • 输入参数2:位移对象(在原来ida文件中该墙体对应的编号)(要求为可迭代对象
  • 输入参数3:原来ida文件的路径
  • 输入参数4:新的ida文件的路径,缺省时默认为原有ida文件路径,进行覆盖
from collections import Iterable
from math import log10, ceil
import re# 读取初始ida文件
def read_origin_ida_file(_path: str):with open(_path, 'r') as f:raw = f.read()wall_index = raw.find('BEGIN_WALLS')tmp = raw[wall_index + 12:-11].split('\n')amount = int(tmp[0])return amount, tmp[1:]# 找到目标语句
def find_target_sentences(_index: Iterable, _path: str):amount, sentences = read_origin_ida_file(_path)found = 0target_sentences = list()for _ in sentences:if int(re.split(r'\s+', _)[0]) in _index:found += 1target_sentences.append(_)if len(target_sentences) != len(_index):print("Invalid index exists")return Nonereturn target_sentencesdef construct_new_ida_file(_gain: Iterable, _index: Iterable, _input_path, _output_path=None):if not _output_path:_output_path = _input_pathtarget_sentences = find_target_sentences(_index, _input_path)if not target_sentences:print("Error!")returnnew_sentences = list()for _ in _gain:for __ in target_sentences:tmp = list(filter(lambda i: i, re.split(r'\s+|,', __)))for ___ in range(12):tmp[___ + 2] = '%.6f' % (float(tmp[___ + 2]) + _[___ % 3])new_sentences.append(' '.join(tmp))print(new_sentences)with open(_input_path, 'r') as f:raw = f.read()wall_index = raw.find('BEGIN_WALLS')new_content = raw[:wall_index + 12]tmp = re.split('\n', raw[wall_index + 12:-11])pre_len = int(tmp[0])new_content += str(pre_len + len(new_sentences))new_content += raw[wall_index + 12 + ceil(log10(int(tmp[0]))):-12] + ' \n'for index, sentence in enumerate(new_sentences):_ = re.split(r'\s+', sentence)new_content += str(index + 1 + pre_len) + ' ' + _[1] + '  ' + _[2] + ', ' + _[3] + ',' + _[4] + '  ' + _[5] + ', ' + _[6] + ',' + _[7] + '  ' + _[8] + ', ' + _[9] + ',' + _[10] + '  ' + _[11] + ', ' + _[12] + ',' + _[13] + '  ' + _[14] + ' ' + _[15] + ' \n'new_content += r'END_WALLS\n'print(new_content)with open(_output_path, 'w') as f:f.write(new_content)if __name__ == '__main__':construct_new_ida_file(([12, 12, 12], [10, 10, 10]), list(range(1, 13)),'D:/Desktop/等会就删.ida', 'D:/Desktop/hahahai.ida')

实验

不考虑实用性,假如这样一个场景:小正方体沿着圆柱盘旋上升,该怎么画?
选取位移对象是简单的,可以随便构造一个 1 × 1 × 1的立方体即可。关键在于对于位移的构造。
尝试使用极坐标的思想,让小正方体每次位移2,位移角度每次增加30°,同时高度每次增加0.2,
构造40个试试:

from math import cos, sin, pi
result = list()
result.append([2, 0, 0])
angle = 0
theta_z = 0.2
for _ in range(39):angle += pi / 6base = result[-1]theta_x = 2 * cos(angle)theta_y = 2 * sin(angle)result.append([base[0] + theta_x, base[1] + theta_y, base[2] + theta_z])print(result)

效果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/259383.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式day24

开课复工啦~ 冲冲冲! 文件IO: read函数和write函数: 📚 write 接口有三个参数: fd:文件描述符buf:要写入的缓冲区的起始地址(如果是字符串,那么就是字符串的起始地址&…

算法学习系列(三十五):贪心(杂)

目录 引言一、合并果子(Huffman树)二、排队打水(排序不等式)三、货仓选址(绝对值不等式)四、耍杂技的牛(推公式) 引言 上一篇文章也说过了这个贪心问题没有一个规范的套路和模板&am…

第三十三回 镇三山大闹青州道 霹雳火夜走瓦砾场-python分割字符串

黄信和刘知寨押解宋江和花荣向青州走,碰到了燕顺等三人来劫囚车,黄信逃走了,刘知寨被抓住,被花荣一刀杀了。 黄信把情况报给青州知府,派来了青州兵马秦统制,人称霹雳火的秦明。秦明与花荣打,花…

UnityShader——06UnityShader介绍

UnityShader介绍 UnityShader的基础ShaderLab UnityShader属性块介绍 Properties {//和public变量一样会显示在Unity的inspector面板上//_MainTex为变量名,在属性里的变量一般会加下划线,来区分参数变量和临时变量//Texture为变量命名//2D为类型&…

如何用Qt实现一个无标题栏、半透明、置顶(悬浮)的窗口

在Qt框架中,要实现一个无标题栏、半透明、置顶(悬浮)的窗口,需要一些特定的设置和技巧。废话不多说,下面我将以DrawClient软件为例,介绍一下实现这种效果的四个要点。 要点一:移除标题栏&#…

SG5032EAN规格书

SG5032EAN 晶体振荡器结合了相位锁定环(PLL)技术和AT切割晶体单元,提供了73.5 MHz至700 MHz的广泛频率范围,以满足高速数字应用的需求。高性能的LV-PECL输出,2.5V和3.3V电源电压,可灵活适配不同设计的电源需…

vue3 之 商城项目—封装SKU组件

认识SKU组件 SKU组件的作用 产出当前用户选择的商品规格,为加入购物车操作提供数据信息,在选择的过程中,组件的选中状态要进行更新,组件还要提示用户当前规格是否禁用,每次选择都要产出对应的sku数据 SKU组件的使用 …

物奇平台DRC动态范围控制修改方法

物奇平台DRC动态范围控制修改 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙耳机音频,DSP音频项目核心开发资料, 音频 DRC 是指动态范围控制(Dyna

suse15 sp3-sp5离线安装中安装FIO

没有网络的情况下,离线安装相对比较困难一点,所有需要提前下载相应的RPM安装包 FIO 安装包链接如下: Install package benchmark / fio 正常安装的时候,会出现问题 如下: google下 https://opensuse.pkgs.org/15.5/…

Spring Boot 笔记 024 登录页面

1.1 登录接口 //导入request.js请求工具 import request from /utils/request.js//提供调用注册接口的函数 export const userRegisterService (registerData)>{//借助于UrlSearchParams完成传递const params new URLSearchParams()for(let key in registerData){params.a…

IOS破解软件安装教程

对于很多iOS用户而言,获取软件的途径显得较为单一,必须通过App Store进行下载安装。 这样的限制,时常让人羡慕安卓系统那些自由下载各类版本软件的便捷。 心中不禁生出疑问:难道iOS世界里,就不存在所谓的“破解版”软件…

vue-自定义创建项目(六)

为什么要自定义创建项目? 因为VueCli默认创建的项目不能够满足我们的要求,比如默认的项目中没有帮我们集成路由,vuex,eslink等功能。 默认项目 自定义创建项目 流程: 创建项目命令:vue create custom_dem…

【嵌入式学习】IO网络接口day02.18

1.使用fgets统计给定文件的行数 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, const char *argv[]) {FILE *fpNULL;if((fpfopen("./test1.txt","r"))NULL){perror("错误信息");return -1…

C语言从零实现贪吃蛇小游戏

制作不易&#xff0c;点赞关注一下呗&#xff01;&#xff01;&#xff01; 文章目录 前言一. 技术要点二、WIN32API介绍三、贪吃蛇游戏设计与分析 1.游戏开始前的初始化 2.游戏运行的逻辑 总结 前言 当我们掌握链表这样的数据结构之后&#xff0c;我们就可以用它来…

Go语言每日一练——链表篇(八)

传送门 牛客面试笔试必刷101题 ----------------两个链表的第一个公共结点 题目以及解析 题目 解题代码及解析 解析 这一道题使用的还是双指针算法&#xff0c;我们先求出两个链表的长度差n&#xff0c;然后定义快慢指针&#xff0c;让快指针先走n步&#xff0c;最后快慢指…

基于SSM的社区疫情防控管理系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的社区疫情防控管理系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spri…

拿捏c语言指针(中)

前言 书接上回 拿捏c语言指针&#xff08;上&#xff09; 此篇主要讲解的是指针与数组之间的爱恨情仇&#xff0c;跟着我的脚步一起来看看吧~ 创造不易&#xff0c;可以帮忙点点赞吗 如有差错&#xff0c;欢迎指出 理解数组名 数组名是首元素地址 例外 1.sizeof&#xff0…

C#使用迭代器实现文字的动态效果

目录 一、涉及到的知识点 1.GDI 2.Thread类 3.使用IEnumerable()迭代器 二、实例 1.源码 2.生成效果&#xff1a; 一、涉及到的知识点 1.GDI GDI主要用于在窗体上绘制各种图形图像。 GDI的核心是Graphics类&#xff0c;该类表示GDI绘图表面&#xff0c;它提供将对象绘制…

在UE5中使用体积材质

在平时使用UE的材质设置时&#xff0c;经常会看见Material Domain Volume类型&#xff0c;但是却很少使用。其实该类型可以配合体积雾使用&#xff0c;并制作体积效果以弥补自带雾参数的不足。 操作流程 首先找到场景中的ExponentialHeightFog组件&#xff0c;开启体积雾Volu…

c++阶梯之类与对象(下)

前文&#xff1a; c阶梯之类与对象&#xff08;上&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;&#xff1c; 续集 &#xff1e;-CSDN博客 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&a…