feat: Initial esp32-hacking project with firmware sources and docs
This commit is contained in:
13
esp-radar/console_test/CMakeLists.txt
Normal file
13
esp-radar/console_test/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
add_compile_options(-fdiagnostics-color=always)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/advanced/components)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
string(REGEX REPLACE ".*/\(.*\)" "\\1" CURDIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
project(${CURDIR})
|
||||
|
||||
git_describe(PROJECT_VERSION ${COMPONENT_DIR})
|
||||
message("Project commit: " ${PROJECT_VERSION})
|
||||
178
esp-radar/console_test/README.md
Normal file
178
esp-radar/console_test/README.md
Normal file
@@ -0,0 +1,178 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
|
||||
# esp-csi console_test [[中文]](./README_cn.md)
|
||||
----------
|
||||
## 1 Introduction
|
||||
This example provides a test platform for Wi-Fi CSI, which includes functions such as data display, data acquisition and data analysis, which can help you quickly understand Wi-Fi CSI.
|
||||
+ **Display**:you can quickly understand the impact of different antennas, human movement and equipment placement on Wi-Fi signals by viewing the real-time data such as Wi-Fi RF noise bottom, CSI, RSSI and noise floor of RF.
|
||||
+ **Acquisition**:All collected Wi-Fi CSIS will be stored in files. You can also mark the data for different motor behaviors for later neural network and machine learning.
|
||||
+ **Analysis**:It can realize the detection of human movement and whether there are people in the room, and help you quickly the application scenario of Wi-Fi CSI.
|
||||
## 2 Equipment preparation
|
||||
### 2.1 Equipment
|
||||

|
||||
This example provides two working modes of `ESP32 DevKitC development board` and `router` as Wi-Fi CSI contracting equipment. Using `ESP32 DevKitC development board` as contracting equipment has better adjustment effect on contracting rate, RF size and channel. In both modes, `ESP32 DevKitC development board` is used as the receiving device for Wi-Fi CSI.
|
||||
|
||||
### 2.2 Compiler Environment
|
||||
The esp-idf version of the current project is [ESP-IDF Release v5.0.2](https://github.com/espressif/esp-idf/releases/tag/v5.0.2)
|
||||
```bash
|
||||
cd esp-idf
|
||||
git checkout v5.0.2
|
||||
git submodule update --init --recursive
|
||||
./install.sh
|
||||
. ./export.sh
|
||||
```
|
||||
> Note: Since esp-idf v5.0.0 or above supports destination address filtering, the effect will be better, so it is recommended to use v5.0.0 or above
|
||||
|
||||
## 3 Starting program
|
||||
### 3.1 Send Wi-Fi CSI
|
||||
+ **Use `ESP32 DevKitC` to send CSI**:Burn project `csi_send` to `ESP32 DevKitC development board`
|
||||
|
||||
```bash
|
||||
cd esp-csi/examples/get-started/csi_send
|
||||
idf.py set-target esp32s3
|
||||
idf.py flash -b 921600 -p /dev/ttyUSB0 monitor
|
||||
```
|
||||
+ **Use router to send CSI**:The router is not connected to other intelligent devices to avoid network congestion affecting the test effect.
|
||||
|
||||
### 3.2 Receive Wi-Fi CSI
|
||||
+ Burn project `console_test` to another `ESP32 DevKitC development board`
|
||||
```bash
|
||||
cd esp-csi/examples/console_test
|
||||
idf.py set-target esp32s3
|
||||
idf.py flash -b 921600 -p /dev/ttyUSB1
|
||||
```
|
||||
|
||||
### 3.3 Start up `esp-csi-tool`. Open the CSI visualization interface
|
||||
+ Run `esp_csi_tool.py` in `csi_recv` for data analysis. Please close `idf.py monitor` before running. Please use UART port instead of USB Serial/JTAG port.
|
||||
```bash
|
||||
cd esp-csi/examples/console_test/tools
|
||||
# Install python related dependencies
|
||||
pip install -r requirements.txt
|
||||
# Graphical display
|
||||
python esp_csi_tool.py -p /dev/ttyUSB1
|
||||
```
|
||||
+ After running successfully, the following CSI data visualization interface is opened. The left side of the interface is the data display interface `Raw data`, and the right side is the data model interface `Raw model`:
|
||||
|
||||
## 4 Interface introduction
|
||||
The real-time visualization interface consists of two parts: the `Raw data` and the `Radar model`. `Raw data` displays the original CSI sub-carrier data, and `Radar model` uses algorithms to analyze the CSI data. As a result, it can be used for detection of someone/noneone, move/static, by selecting the `Raw data` and `Radar model` buttons in the upper right corner, you can choose to display the two interfaces separately.
|
||||
|
||||
### 4.1 Router connection window
|
||||
The top left is the configuration router connection information window. Use the device to connect to the router and receive the CSI between the router and the device.
|
||||
|
||||

|
||||
|
||||
+ **SSID**:router account
|
||||
+ **password**:router password
|
||||
+ **auto connect**:If checked, the next time you turn it on, it will automatically connect to the last connected router.
|
||||
+ **connect / disconnect**:connect/disconnect button
|
||||
+ **custom**:You can send more control commands such as: restart, version acquisition, or enter custom commands on the device side
|
||||
|
||||
### 4.2 CSI data waveform display window
|
||||
This window can display the waveform of some channel CSI data in real time. If `wave filtering` is checked, the filtered waveform will be displayed.
|
||||

|
||||
|
||||
### 4.3 RSSI waveform display window
|
||||
This window displays the RSSI waveform information, which can be used to compare with the CSI waveform to observe the changes of RSSI when the personnel in the room are in different states.
|
||||

|
||||
|
||||
### 4.4 log display window
|
||||
This window displays system logs such as time, memory, etc.
|
||||

|
||||
|
||||
### 4.5 Wi-Fi channel data display window
|
||||
This window displays Wi-Fi channel status information.
|
||||

|
||||
|
||||
### 4.6 Room status display window
|
||||
This window is used to calibrate the room status threshold and display room status ( someone/noneone, move/static ).
|
||||
|
||||
+ **delay**:start calibration delay time, no one is required in the room during calibration, and people can leave the room within the delay time after starting calibration.
|
||||
+ **duration**:calibration process duration.
|
||||
+ **add**:if checked, the recalibrated threshold will be accumulated based on the current threshold.
|
||||
+ **start**:start calibration button.
|
||||
+ **wander(someone) threshold**:the threshold for judging room presence/absence will be set automatically after calibration, or can be set manually by the user.
|
||||
+ **jitter(move) threshold**:the threshold for judging the move/static of people will be set automatically after calibration, or it can be set manually by the user.
|
||||
+ **config**:after the user manually sets the threshold, click the configure button.
|
||||
+ **display table**:if checked, the room status and people status information table will be displayed on the right side of the waveform box. The specific parameters in the table are as follows.
|
||||
|
||||
|status|threshold|value|max|min|mean|std|
|
||||
|---|---|---|---|---|---|---|
|
||||
|room/people status|Judgment threshold|real-time value|maximum value|minimum value|average value|standard deviation|
|
||||
|
||||
### 4.7 People movement data display window
|
||||
This window displays the specific data of indoor people's movement, the bar graph on the left shows the number of people's movement in real time, and the table on the right records the specific movement time.
|
||||

|
||||
|
||||
+ **mode**:observation mode, `minute, hour, day` three modes are to record the number of people's movements per minute, hour, and day.
|
||||
+ **time**:observation time, the default current time, you can manually set the time to start the observation.
|
||||
+ **auto update**:if checked, the bar graph of the number of people's movements will be automatically updated and displayed in real time.
|
||||
+ **update**:after clicking, the bar graph of the number of people's movements will be manually updated and displayed.
|
||||
|
||||
The meaning of each parameter in the table is as follows:
|
||||
|room|human|spend_time|start_time|stop_time|
|
||||
|---|---|---|---|---|
|
||||
|room status|people status|spend time of movement|start time of movement|stop time of movement|
|
||||
|
||||
### 4.8 Action collection window
|
||||
This window is used to collect CSI data when people perform different actions. The collected data will be stored under the path of `esp-csi/examples/console_test/tools/data`, and the collected data can be used for machine learning or neural network.
|
||||

|
||||
|
||||
+ **target**:Select the motor behaviors to collect
|
||||
+ **delay**:Select the delay time of collection, which is how long to wait after clicking the `start` button
|
||||
+ **duration**:The duration of collecting an action
|
||||
+ **number**:Collection times
|
||||
+ **clean**:Click to clear all collected data
|
||||
+ **start**:start collecting button
|
||||
|
||||
## 5 Operating procedures
|
||||
Here, taking connecting the router as an example, the operation flow of the visualization system interface is introduced.
|
||||
### 5.1 connect router
|
||||
+ Enter the router account and password in turn in the router connection window
|
||||
+ (option)check `auto connect`
|
||||
+ Click `connect`
|
||||
|
||||
After the connection is successful, you will see the router status information in the "log print window", and the "CSI data waveform display window" will display the CSI data waveform.
|
||||
|
||||
### 5.2 Calibration threshold
|
||||
The purpose of calibration is to let the device know the CSI information when there is no one in the room, and to obtain the threshold of personnel movement. If the current version does not calibrate, only personnel movement detection can be performed. The longer the calibration time, the lower the probability of false touches.
|
||||

|
||||
|
||||
+ Set the delay time of `delay`, here is 10 seconds for example (i.e. 00:00:10), so that people can leave the room.
|
||||
+ Set the duration of `duration` calibration, here is 10 seconds as an example.
|
||||
+ Click `start` and select `yes`, the person leaves the room within 10 seconds (`delay` time), ensure that there is no one in the room within 10 seconds during the calibration period (`duration` calibration duration), and return to the room after the calibration.
|
||||
+ ( option ) to manually adjust the room status threshold and the person status threshold based on the calibration results.
|
||||
|
||||
### 5.3 Observe room status and people status
|
||||
|
||||
After the calibration is completed, the room status will be displayed in the room status display window, and it will be judged that there is noneone static, someone moves, and someone static three status.
|
||||
|
||||
+ In `filter outliers`, set how many times the threshold is reached in a row to determine the room/people state, so as to filter outliers.
|
||||
+ Click `config` to configure.
|
||||
+ ( option ) In the room status waveform window, click the horizontal line in front of `wander` to hide its waveform, which is convenient for observing other waveforms. Similarly, other waveforms can also be hidden by the following method.
|
||||
+ ( option ) Check `display table` to view the indoor status and people status information table.
|
||||
|
||||
### 5.4 Observer movement times and the time
|
||||
In these observation windows, the number of people's movements per minute will be displayed in a histogram according to our settings. The time information of each movement is recorded in the table on the right.
|
||||

|
||||
|
||||
+ In the `mode` of the people's movement data display window, select the observation mode to view the movement of the people in the room in one minute, one hour or one day. Here, choose `minute` as an example.
|
||||
+ ( option ) Set the time to start the observation in `time`, the default is the current time start.
|
||||
+ Check `auto update` to automatically update the test results, if not checked, each time you click `update`, the test results will be updated once.
|
||||
|
||||
### 5.5 Collect CSI data for a specific action
|
||||

|
||||
+ ( option ) Clear previous acquisition data records in `clean` in the motion acquisition window.
|
||||
+ In `target`, select the action to be collected, here select `move` as an example.
|
||||
+ In `delay`, set the delayed acquisition time after clicking to start, here is an example of setting a delay of 5 seconds.
|
||||
+ In `duration`, set the duration of collecting an action in, here we choose 500 ms as an example.
|
||||
+ In `number`, set the number of times to be collected, here is 1 collection as an example.
|
||||
+ Click `start`, the system will start collecting data after the delay time, and the personnel will complete the corresponding action within the set time.
|
||||
|
||||
After the collection is over, it will stop automatically. We can see the data we collected under the path of `esp-csi/examples/esp-radar/console_test/tools/data`.
|
||||

|
||||
|
||||
### 5.6 Window zoom in and out
|
||||

|
||||
+ By selecting `Raw data` and `Radar model` in the upper right corner of the interface, the `Raw data` interface and `Radar model` interface can be displayed separately.
|
||||
+ Select the critical line between different windows with the mouse, and drag and drop to zoom in/out of each window.
|
||||
180
esp-radar/console_test/README_cn.md
Normal file
180
esp-radar/console_test/README_cn.md
Normal file
@@ -0,0 +1,180 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
|
||||
# esp-csi console_test [[English]](./README.md)
|
||||
----------
|
||||
## 1 简介
|
||||
console_test 是一款 Wi-Fi CSI 的测试平台,它包含了对 Wi-Fi CSI 的数据采集、数据显示、数据分析等功能,帮助我们更好的了解和应用 Wi-Fi CSI
|
||||
+ **显示**:通过查看 Wi-Fi 射频底噪、CSI、RSSI 及射频底噪等实时数据,可以快速了解不同天线、人体运动和设备摆放对 Wi-Fi 信号的影响。
|
||||
+ **采集**:所有采集到的 Wi-Fi CSI 将存储在文件中。您还可以采集不同运动行为的数据,以供以后的神经网络和机器学习使用
|
||||
+ **分析**:可实现检测人体是否运动及房间内是否有人,帮助您快速了解 Wi-Fi CSI 的应用场景
|
||||
|
||||
## 2 环境准备
|
||||
### 2.1 设备
|
||||

|
||||
本例提供了 `ESP32 DevKitC 开发板` 和 `路由器` 两种设备模式作为 Wi-Fi CSI 发送设备。 其中使用 `ESP32 DevKitC 开发板` 作为发送设备,对发送频率、射频大小、信道的调整效果更好。两种模式下都用 `ESP32 DevKitC 开发板` 作为 Wi-Fi CSI 的接收设备。
|
||||
|
||||
### 2.2 编译环境
|
||||
使用的 esp-idf 版本为 [ESP-IDF Release v5.0.2](https://github.com/espressif/esp-idf/releases/tag/v5.0.2)
|
||||
```bash
|
||||
cd esp-idf
|
||||
git checkout v5.0.2
|
||||
git submodule update --init --recursive
|
||||
./install.sh
|
||||
. ./export.sh
|
||||
```
|
||||
> 注: 由于 esp-idf v5.0.0 以上的版本支持目的地址过滤,其效果会更好,因此建议使用 v5.0.0 以上的版本
|
||||
|
||||
## 3 程序启动
|
||||
### 3.1 发送 Wi-Fi CSI
|
||||
+ ** `ESP32 DevKitC 开发板` 发送 CSI**:烧录工程 `csi_send` 到 `ESP32 DevKitC 开发板` 中
|
||||
```bash
|
||||
cd esp-csi/examples/get-started/csi_send
|
||||
idf.py set-target esp32s3
|
||||
idf.py flash -b 921600 -p /dev/ttyUSB0 monitor
|
||||
```
|
||||
+ **路由器 发送 CSI**:此时路由器不连接其他智能设备,避免网络拥塞影响测试效果
|
||||
|
||||
### 3.2 接收 Wi-Fi CSI
|
||||
+ 烧录 `console_test` 到另一块 `ESP32 DevKitC 开发板` 开发板中
|
||||
```bash
|
||||
cd esp-csi/examples/console_test
|
||||
idf.py set-target esp32s3
|
||||
idf.py flash -b 921600 -p /dev/ttyUSB1
|
||||
```
|
||||
|
||||
### 3.3 启动 `esp-csi-tool` 工具,打开 CSI 实时可视化工具,请使用 UART 口而不是 USB Serial/JTAG 口
|
||||
+ 运行 `csi_recv` 中的 `esp_csi_tool.py` 进行数据分析,运行前请关闭 `idf.py` 监控
|
||||
```bash
|
||||
cd esp-csi/examples/console_test/tools
|
||||
# Install python related dependencies
|
||||
pip install -r requirements.txt
|
||||
# Graphical display
|
||||
python esp_csi_tool.py -p /dev/ttyUSB1
|
||||
```
|
||||
+ 运行成功后,打开如下 CSI 数据实时可视化界面,界面左侧为数据显示界面,右侧为数据模型界面:
|
||||

|
||||
|
||||
## 4 界面介绍
|
||||
实时可视化界面由数据显示界面 `Raw data` 和数据模型界面 `Radar model` 两部分组成,`Raw data` 显示原始的 CSI 各个子载波的数据,`Radar model` 是使用算法对 CSI 数据分析后的结果,可以用于有人/无人、运动/静止的检测,通过选择勾选右上角 `Raw data` 和 `Radar model` 按钮,可以选择单独显示两个界面
|
||||
|
||||
### 4.1 路由器连接窗口:
|
||||
左侧最上方为配置路由器连接信息窗口,使用设备连接到路由器上,接收路由器的与设备之间 CSI
|
||||
|
||||

|
||||
|
||||
+ **ssid**:路由器帐号
|
||||
+ **password**:路由器密码
|
||||
+ **auto connect**:如果勾选,下次打开时,将自动连接上次连接的路由器
|
||||
+ **connect / disconnect**:连接/断开按钮
|
||||
+ **custom**:可以发送更多的控制指令如:重启、版本获取,或者输入设备端自定义的命令
|
||||
|
||||
### 4.2 CSI 数据波形显示窗口
|
||||
此窗口可实时显示部分通道 CSI 数据的波形,如果勾选 `wave filtering`,显示的就是滤波后的波形
|
||||

|
||||
|
||||
### 4.3 RSSI 波形显示窗口
|
||||
此窗口显示 RSSI 波形信息,可用于与 CSI 波形比较,观测室内人员处于不同处态时 RSSI 变化情况
|
||||

|
||||
|
||||
### 4.4 log 显示窗口
|
||||
此窗口显示时间,内存等系统日志
|
||||

|
||||
|
||||
### 4.5 Wi-Fi 信道数据显示窗口
|
||||
此窗口显示 Wi-Fi 信道状态信息
|
||||

|
||||
|
||||
### 4.6 室内状态显示窗口
|
||||
此窗口用于校准室内状态阈值,和显示室内状态(有人/无人、运动/静止)
|
||||

|
||||
|
||||
+ **delay**:开始校准延迟时间,校准时要求室内无人,人员可在开始校准后,延迟时间内离开房间
|
||||
+ **duration**:校准过程持续时间
|
||||
+ **add**:如果勾选,再次校准后的阈值将在当前阈值基础上累加
|
||||
+ **start**:开始校准按钮
|
||||
+ **wander(someone) threshold**:判断室内有人/无人的阈值,将在校准后自动设置,也可以用户自己手动设置
|
||||
+ **jitter(move) threshold**:判断人员静止/运动的阈值,将在校准后自动设置,也可以用户自己手动设置
|
||||
+ **config**:用户手动设置阈值后,点击配置按钮
|
||||
+ **display table**:如果勾选,将在波形框右侧显示室内状态和人员状态信息表格,表格中具体参数如下
|
||||
|
||||
|status|threshold|value|max|min|mean|std|
|
||||
|---|---|---|---|---|---|---|
|
||||
|状态|阈值|实时值|最大值|最小值|平均值|标准差|
|
||||
|
||||
### 4.7 人员运动数据显示窗口
|
||||
此窗口显示室内人员运动的具体数据,左侧以柱状图实时显示人员运动次数,右侧表格记录具体运动时间
|
||||

|
||||
|
||||
+ **mode**:观测模式,`minute, hour, day` 三种模式分别为以每分钟、每小时、每天为单位记录人员运动的次数
|
||||
+ **time**:时间,默认当前时间,可手动设置开始观测的时间
|
||||
+ **auto update**:如果勾选,会自动实时更新显示人员运动次数柱状图
|
||||
+ **update**:点击后会手动更新显示人员运动次数柱状图
|
||||
|
||||
表格各参数意义如下:
|
||||
|room|human|spend_time|start_time|stop_time|
|
||||
|---|---|---|---|---|
|
||||
|房间状态|人员状态|运动时长|运动开始时间|运动结束时间|
|
||||
|
||||
### 4.8 动作采集窗口
|
||||
此窗口用于对人员做不同动作时的 CSI 数据进行采集,采集的数据将存储在 `esp-csi/examples/console_test/tools/data` 路径下,采集的数据可用于机器学习或神经网络
|
||||

|
||||
|
||||
+ **target**:选择要采集的动作
|
||||
+ **delay**:选择采集的延迟时间,即点击开始按钮后延迟多久开始采集
|
||||
+ **duration**:采集一次动作持续时长
|
||||
+ **number**:采集次数
|
||||
+ **clean**:点击后将清除所采集的所有数据
|
||||
+ **start**:开始采集按钮
|
||||
|
||||
## 5 操作流程
|
||||
这里以连接路由器为例,介绍了可视化系界面使用的操作流程
|
||||
### 5.1 连接路由器
|
||||
+ 在路由器连接窗口中依次输入路由器帐号和密码
|
||||
+ (可选)勾选 `auto connect`
|
||||
+ 点击 `connect`
|
||||
|
||||
连接成功后,将在 “log 打印窗口” 看到路由器状态信息,同时 “CSI 数据波形显示窗口” 显示 CSI 数据波形
|
||||
|
||||
### 5.2 校准阈值
|
||||
校准的目的是为让设备知晓房间无人状态下的 CSI 信息,并获取到人员移动的阈值,当前版本如果不校准仅能进行人员移动检测,校准时间越长误触的概率越低
|
||||

|
||||
|
||||
+ 设置 `delay` 延迟时间,这里设置 10 秒为例(即 00:00:10),以便人员可以离开房间
|
||||
+ 设置 `duration` 校准持续时长, 这里设置 10 秒为例
|
||||
+ 点击 `start` 后选择 `yes`,人员 10 秒(`delay` 延迟时间)内离开房间,确保校准期间 10 秒内(`duration` 校准持续时长)房间内无人,校准结束后返回房间
|
||||
+ (选择)可根据校准结果,手动调整房间状态阈值和人员状态阈值
|
||||
|
||||
### 5.3 观测房间状态和人员状态
|
||||
校准结束后,室内状态显示窗口中将显示室内状态,并判断房间内无人、有人静止、有人运动三种状态
|
||||

|
||||
|
||||
+ 在 `filter outliers` 中设置连续多少次内达到阈值多少次判定为有人/运动状态,以便过滤异常值
|
||||
+ 点击 `config` 进行配置
|
||||
+ (选择)在房间状态波形窗口,点击 `wander` 前的横线,可隐藏其波形,方便观测其他波形,同样其他波形也可以用次方法隐藏
|
||||
+ (选择)勾选 `display table` ,查看室内状态和人员状态信息表格
|
||||
|
||||
### 5.4 观测人员运动次数和时间
|
||||
在些观测窗口中,将会按照我们的设置以柱状图显示人员每分钟的运动数量在右侧表格中记录了每次运动时间信息。
|
||||

|
||||
|
||||
+ 在人员运动数据显示窗口的 `mode` 中,选择观测模式,可以查看某分钟、某小时或某天房间内人员的运行情况,这里选择 `minute` 为例
|
||||
+ (选择)在 `time` 中设置开始观测的时间,默认为当前时刻开始
|
||||
+ 勾选 `auto update` 自动更新检测结果,如果不勾选,每次点击 `update` 会更新一次检测结果
|
||||
|
||||
### 5.5 采集特定动作的 CSI 数据
|
||||

|
||||
+ (选择)在动作采集窗口的 `clean` 中清除以前的采集数据记录
|
||||
+ 在 `target` 中选择将要采集的动作,这里选择 `move` 为例
|
||||
+ 在 `delay` 中设置点击开始后的延迟采集时间,这里设置延迟 5 秒为例
|
||||
+ 在 `duration` 中设置采集一个动作持续的时间,这里选择 500 ms 为例
|
||||
+ 在 `number` 中设置要采集的次数,这里采集 1 次为例
|
||||
+ 点击 `start`,经过延迟时间后系统将开始采集数据,人员在设置时间内完成对应动作
|
||||
|
||||
采集结束后会自动停止,我们在 `esp-csi/examples/esp-radar/console_test/tools/data` 路径下可以看到我们采集的数据
|
||||

|
||||
|
||||
### 5.6 窗口放大与缩小
|
||||

|
||||
+ 通过选择勾选界面右上角 `Raw data` 与 `Radar model`,可单独显示 “数据显示界面” 和 “数据模型界面”
|
||||
+ 鼠标选中不同窗口间的临界线,通过拖拽可放大/缩小各窗口
|
||||
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRC_DIRS "src"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES "console" "mbedtls" "nvs_flash" "fatfs" "esp_wifi" "spi_flash")
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
31
esp-radar/console_test/components/commands/include/csi_commands.h
Executable file
31
esp-radar/console_test/components/commands/include/csi_commands.h
Executable file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "esp_console.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /**< _cplusplus */
|
||||
|
||||
void cmd_register_ping(void);
|
||||
void cmd_register_system(void);
|
||||
void cmd_register_wifi_config(void);
|
||||
void cmd_register_wifi_scan(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /**< _cplusplus */
|
||||
225
esp-radar/console_test/components/commands/src/ping_cmd.c
Normal file
225
esp-radar/console_test/components/commands/src/ping_cmd.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "nvs_flash.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_console.h"
|
||||
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#include "ping/ping_sock.h"
|
||||
|
||||
static const char *TAG = "ping_cmd";
|
||||
|
||||
esp_ping_handle_t g_ping_handle = NULL;
|
||||
|
||||
static void ping_cmd_on_success(esp_ping_handle_t hdl, void *args)
|
||||
{
|
||||
uint8_t ttl;
|
||||
uint16_t seqno;
|
||||
uint32_t elapsed_time, recv_len;
|
||||
ip_addr_t target_addr;
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_TTL, &ttl, sizeof(ttl));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
|
||||
ESP_LOGD(TAG, "%d bytes from %s icmp_seq=%d ttl=%d time=%d ms",
|
||||
recv_len, ipaddr_ntoa((ip_addr_t *)&target_addr), seqno, ttl, elapsed_time);
|
||||
}
|
||||
|
||||
static void ping_cmd_on_timeout(esp_ping_handle_t hdl, void *args)
|
||||
{
|
||||
uint16_t seqno;
|
||||
ip_addr_t target_addr;
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||
ESP_LOGW(TAG, "From %s icmp_seq=%d timeout", ipaddr_ntoa((ip_addr_t *)&target_addr), seqno);
|
||||
}
|
||||
|
||||
static void ping_cmd_on_end(esp_ping_handle_t hdl, void *args)
|
||||
{
|
||||
ip_addr_t target_addr;
|
||||
uint32_t transmitted;
|
||||
uint32_t received;
|
||||
uint32_t total_time_ms;
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_REQUEST, &transmitted, sizeof(transmitted));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_REPLY, &received, sizeof(received));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms));
|
||||
uint32_t loss = (uint32_t)((1 - ((float)received) / transmitted) * 100);
|
||||
|
||||
if (IP_IS_V4(&target_addr)) {
|
||||
ESP_LOGI(TAG, "\n--- %s ping statistics ---", inet_ntoa(*ip_2_ip4(&target_addr)));
|
||||
} else {
|
||||
ESP_LOGI(TAG, "\n--- %s ping statistics ---", inet6_ntoa(*ip_2_ip6(&target_addr)));
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "%d packets transmitted, %d received, %d%% packet loss, time %dms",
|
||||
transmitted, received, loss, total_time_ms);
|
||||
// delete the ping sessions, so that we clean up all resources and can create a new ping session
|
||||
// we don't have to call delete function in the callback, instead we can call delete function from other tasks
|
||||
esp_ping_delete_session(hdl);
|
||||
g_ping_handle = NULL;
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct arg_int *timeout;
|
||||
struct arg_int *interval;
|
||||
struct arg_int *data_size;
|
||||
struct arg_int *count;
|
||||
struct arg_int *tos;
|
||||
struct arg_str *host;
|
||||
struct arg_lit *abort;
|
||||
struct arg_end *end;
|
||||
} ping_args;
|
||||
|
||||
static int wifi_cmd_ping(int argc, char **argv)
|
||||
{
|
||||
esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
|
||||
config.count = 0;
|
||||
config.data_size = 1;
|
||||
config.interval_ms = 10;
|
||||
config.task_stack_size = 3072;
|
||||
|
||||
if (arg_parse(argc, argv, (void **)&ping_args) != ESP_OK) {
|
||||
arg_print_errors(stderr, ping_args.end, argv[0]);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (ping_args.timeout->count > 0) {
|
||||
config.timeout_ms = ping_args.timeout->ival[0];
|
||||
}
|
||||
|
||||
if (ping_args.interval->count > 0) {
|
||||
config.interval_ms = ping_args.interval->ival[0];
|
||||
}
|
||||
|
||||
if (ping_args.data_size->count > 0) {
|
||||
config.data_size = ping_args.data_size->ival[0];
|
||||
}
|
||||
|
||||
if (ping_args.count->count > 0) {
|
||||
config.count = ping_args.count->ival[0];
|
||||
}
|
||||
|
||||
if (ping_args.tos->count > 0) {
|
||||
config.tos = ping_args.tos->ival[0];
|
||||
}
|
||||
|
||||
if (ping_args.abort->count > 0) {
|
||||
if (g_ping_handle != NULL) {
|
||||
ESP_LOGI(TAG, "Stopping ping session");
|
||||
esp_ping_stop(g_ping_handle);
|
||||
esp_ping_delete_session(g_ping_handle);
|
||||
g_ping_handle = NULL;
|
||||
ESP_LOGI(TAG, "Ping session stopped and deleted");
|
||||
} else {
|
||||
ESP_LOGW(TAG, "No active ping session to stop");
|
||||
}
|
||||
ESP_LOGW(TAG, "esp_ping stop");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
char host[32] = {0};
|
||||
|
||||
if (ping_args.host->count > 0) {
|
||||
strcpy(host, ping_args.host->sval[0]);
|
||||
} else {
|
||||
esp_netif_ip_info_t local_ip;
|
||||
esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &local_ip);
|
||||
sprintf(host, IPSTR, IP2STR(&local_ip.gw));
|
||||
ESP_LOGI(TAG, "ping router ip:" IPSTR ", gw: " IPSTR, IP2STR(&local_ip.ip), IP2STR(&local_ip.gw));
|
||||
}
|
||||
|
||||
// parse IP address
|
||||
struct sockaddr_in6 sock_addr6;
|
||||
ip_addr_t target_addr;
|
||||
memset(&target_addr, 0, sizeof(target_addr));
|
||||
|
||||
if (inet_pton(AF_INET6, host, &sock_addr6.sin6_addr) == 1) {
|
||||
/* convert ip6 string to ip6 address */
|
||||
ipaddr_aton(host, &target_addr);
|
||||
} else {
|
||||
struct addrinfo hint;
|
||||
struct addrinfo *res = NULL;
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
|
||||
/* convert ip4 string or hostname to ip4 or ip6 address */
|
||||
if (getaddrinfo(host, NULL, &hint, &res) != 0) {
|
||||
printf("ping: unknown host %s\n", host);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (res->ai_family == AF_INET) {
|
||||
struct in_addr addr4 = ((struct sockaddr_in *)(res->ai_addr))->sin_addr;
|
||||
inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4);
|
||||
target_addr.type = IPADDR_TYPE_V4;
|
||||
} else {
|
||||
struct in6_addr addr6 = ((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr;
|
||||
inet6_addr_to_ip6addr(ip_2_ip6(&target_addr), &addr6);
|
||||
target_addr.type = IPADDR_TYPE_V6;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
|
||||
config.target_addr = target_addr;
|
||||
|
||||
/* stop and delete existing ping session if any */
|
||||
if (g_ping_handle != NULL) {
|
||||
ESP_LOGI(TAG, "Stopping existing ping session before starting new one");
|
||||
esp_ping_stop(g_ping_handle);
|
||||
esp_ping_delete_session(g_ping_handle);
|
||||
g_ping_handle = NULL;
|
||||
ESP_LOGI(TAG, "Existing ping session stopped and deleted");
|
||||
}
|
||||
|
||||
/* set callback functions */
|
||||
esp_ping_callbacks_t cbs = {
|
||||
.on_ping_success = ping_cmd_on_success,
|
||||
.on_ping_timeout = ping_cmd_on_timeout,
|
||||
.on_ping_end = ping_cmd_on_end,
|
||||
.cb_args = NULL
|
||||
};
|
||||
|
||||
esp_ping_new_session(&config, &cbs, &g_ping_handle);
|
||||
esp_ping_start(g_ping_handle);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void cmd_register_ping(void)
|
||||
{
|
||||
ping_args.timeout = arg_int0("W", "timeout", "<t>", "Time to wait for a response, in seconds");
|
||||
ping_args.interval = arg_int0("i", "interval", "<t>", "Wait interval seconds between sending each packet");
|
||||
ping_args.data_size = arg_int0("s", "size", "<n>", "Specify the number of data bytes to be sent");
|
||||
ping_args.count = arg_int0("c", "count", "<n>", "Stop after sending count packets");
|
||||
ping_args.tos = arg_int0("Q", "tos", "<n>", "Set Type of Service related bits in IP datagrams");
|
||||
ping_args.host = arg_str0("h", "host", "<host>", "Host address");
|
||||
ping_args.abort = arg_lit0("a", "abort", "Abort running ping");
|
||||
ping_args.end = arg_end(10);
|
||||
const esp_console_cmd_t ping_cmd = {
|
||||
.command = "ping",
|
||||
.help = "Send ICMP ECHO_REQUEST to network hosts",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_ping,
|
||||
.argtable = &ping_args
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&ping_cmd));
|
||||
}
|
||||
264
esp-radar/console_test/components/commands/src/system_cmd.c
Normal file
264
esp-radar/console_test/components/commands/src/system_cmd.c
Normal file
@@ -0,0 +1,264 @@
|
||||
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "mbedtls/base64.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_console.h"
|
||||
#include "esp_chip_info.h"
|
||||
|
||||
|
||||
static const char *TAG = "system_cmd";
|
||||
|
||||
/**
|
||||
* @brief A function which implements version command.
|
||||
*/
|
||||
static int version_func(int argc, char **argv)
|
||||
{
|
||||
esp_chip_info_t chip_info = {0};
|
||||
|
||||
/**< Pint system information */
|
||||
esp_chip_info(&chip_info);
|
||||
ESP_LOGI(TAG, "compile time : %s %s", __DATE__, __TIME__);
|
||||
ESP_LOGI(TAG, "free heap : %d Bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "CPU cores : %d", chip_info.cores);
|
||||
ESP_LOGI(TAG, "silicon revision : %d", chip_info.revision);
|
||||
ESP_LOGI(TAG, "feature : %s%s%s%s",
|
||||
chip_info.features & CHIP_FEATURE_WIFI_BGN ? "/802.11bgn" : "",
|
||||
chip_info.features & CHIP_FEATURE_BLE ? "/BLE" : "",
|
||||
chip_info.features & CHIP_FEATURE_BT ? "/BT" : "",
|
||||
chip_info.features & CHIP_FEATURE_EMB_FLASH ? "/Embedded-Flash:" : "/External-Flash:");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register version command.
|
||||
*/
|
||||
static void register_version()
|
||||
{
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "version",
|
||||
.help = "Get version of chip and SDK",
|
||||
.hint = NULL,
|
||||
.func = &version_func,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief A function which implements restart command.
|
||||
*/
|
||||
static int restart_func(int argc, char **argv)
|
||||
{
|
||||
ESP_LOGI(TAG, "Restarting");
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register restart command.
|
||||
*/
|
||||
static void register_restart()
|
||||
{
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "restart",
|
||||
.help = "Software reset of the chip",
|
||||
.hint = NULL,
|
||||
.func = &restart_func,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A function which implements reset command.
|
||||
*/
|
||||
static int reset_func(int argc, char **argv)
|
||||
{
|
||||
esp_partition_iterator_t part_itra = NULL;
|
||||
const esp_partition_t *nvs_part = NULL;
|
||||
|
||||
ESP_LOGI(TAG, "Erase part of the nvs partition");
|
||||
|
||||
part_itra = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "nvs");
|
||||
nvs_part = esp_partition_get(part_itra);
|
||||
esp_partition_erase_range(nvs_part, 0, nvs_part->size);
|
||||
|
||||
ESP_LOGI(TAG, "Restarting");
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register reset command.
|
||||
*/
|
||||
static void register_reset()
|
||||
{
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "reset",
|
||||
.help = "Clear device configuration information",
|
||||
.hint = NULL,
|
||||
.func = &reset_func,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A function which implements heap command.
|
||||
*/
|
||||
static int heap_func(int argc, char **argv)
|
||||
{
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
||||
TaskStatus_t *pxTaskStatusArray = NULL;
|
||||
volatile UBaseType_t uxArraySize = 0;
|
||||
uint32_t ulTotalRunTime = 0, ulStatsAsPercentage = 0, ulRunTimeCounte = 0;
|
||||
const char task_status_char[] = {'r', 'R', 'B', 'S', 'D'};
|
||||
|
||||
/* Take a snapshot of the number of tasks in case it changes while this
|
||||
function is executing. */
|
||||
uxArraySize = uxTaskGetNumberOfTasks();
|
||||
pxTaskStatusArray = malloc(uxTaskGetNumberOfTasks() * sizeof(TaskStatus_t));
|
||||
|
||||
if (!pxTaskStatusArray) {
|
||||
return ;
|
||||
}
|
||||
|
||||
/* Generate the (binary) data. */
|
||||
uxArraySize = uxTaskGetSystemState(pxTaskStatusArray, uxArraySize, &ulTotalRunTime);
|
||||
ulTotalRunTime /= 100UL;
|
||||
|
||||
ESP_LOGI(TAG, "---------------- The State Of Tasks ----------------");
|
||||
ESP_LOGI(TAG, "- HWM : usage high water mark (Byte)");
|
||||
ESP_LOGI(TAG, "- Status: blocked ('B'), ready ('R'), deleted ('D') or suspended ('S')\n");
|
||||
ESP_LOGI(TAG, "TaskName\t\tStatus\tPrio\tHWM\tTaskNum\tCoreID\tRunTimeCounter\tPercentage");
|
||||
|
||||
for (int i = 0; i < uxArraySize; i++) {
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
ulRunTimeCounte = pxTaskStatusArray[i].ulRunTimeCounter;
|
||||
ulStatsAsPercentage = ulRunTimeCounte / ulTotalRunTime;
|
||||
#else
|
||||
#warning configGENERATE_RUN_TIME_STATS must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
|
||||
#endif
|
||||
|
||||
int core_id = -1;
|
||||
char precentage_char[4] = {0};
|
||||
|
||||
#if ( configTASKLIST_INCLUDE_COREID == 1 )
|
||||
core_id = (int) pxTaskStatusArray[ i ].xCoreID;
|
||||
#else
|
||||
#warning configTASKLIST_INCLUDE_COREID must also be set to 1 in FreeRTOSConfig.h to use xCoreID.
|
||||
#endif
|
||||
|
||||
/* Write the rest of the string. */
|
||||
ESP_LOGI(TAG, "%-16s\t%c\t%u\t%u\t%u\t%hd\t%-16u%-s%%",
|
||||
pxTaskStatusArray[i].pcTaskName, task_status_char[pxTaskStatusArray[i].eCurrentState],
|
||||
(uint32_t) pxTaskStatusArray[i].uxCurrentPriority,
|
||||
(uint32_t) pxTaskStatusArray[i].usStackHighWaterMark,
|
||||
(uint32_t) pxTaskStatusArray[i].xTaskNumber, core_id,
|
||||
ulRunTimeCounte, (ulStatsAsPercentage <= 0) ? "<1" : itoa(ulStatsAsPercentage, precentage_char, 10));
|
||||
}
|
||||
|
||||
free(pxTaskStatusArray);
|
||||
#endif /**< ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 */
|
||||
|
||||
#ifndef CONFIG_SPIRAM_SUPPORT
|
||||
ESP_LOGI(TAG, "Free heap, current: %d, minimum: %d",
|
||||
esp_get_free_heap_size(), esp_get_minimum_free_heap_size());
|
||||
#else
|
||||
ESP_LOGI(TAG, "Free heap, internal current: %d, minimum: %d, total current: %d, minimum: %d",
|
||||
heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL),
|
||||
heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL),
|
||||
esp_get_free_heap_size(), esp_get_minimum_free_heap_size());
|
||||
#endif /**< CONFIG_SPIRAM_SUPPORT */
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register heap command.
|
||||
*/
|
||||
static void register_heap()
|
||||
{
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "heap",
|
||||
.help = "Get the current size of free heap memory",
|
||||
.hint = NULL,
|
||||
.func = &heap_func,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct {
|
||||
struct arg_str *tag;
|
||||
struct arg_str *level;
|
||||
struct arg_end *end;
|
||||
} log_args;
|
||||
|
||||
/**
|
||||
* @brief A function which implements log command.
|
||||
*/
|
||||
static int log_func(int argc, char **argv)
|
||||
{
|
||||
const char *level_str[6] = {"NONE", "ERR", "WARN", "INFO", "DEBUG", "VER"};
|
||||
|
||||
if (arg_parse(argc, argv, (void **)&log_args) != ESP_OK) {
|
||||
arg_print_errors(stderr, log_args.end, argv[0]);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
for (int log_level = 0; log_args.level->count && log_level < sizeof(level_str) / sizeof(char *); ++log_level) {
|
||||
if (!strncasecmp(level_str[log_level], log_args.level->sval[0], sizeof(level_str[log_level]) - 1)) {
|
||||
const char *tag = log_args.tag->count ? log_args.tag->sval[0] : "*";
|
||||
esp_log_level_set(tag, log_level);
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register log command.
|
||||
*/
|
||||
static void register_log()
|
||||
{
|
||||
log_args.tag = arg_str0("t", "tag", "<tag>", "Tag of the log entries to enable, '*' resets log level for all tags to the given value");
|
||||
log_args.level = arg_str0("l", "level", "<level>", "Selects log level to enable (NONE, ERR, WARN, INFO, DEBUG, VER)");
|
||||
log_args.end = arg_end(2);
|
||||
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "log",
|
||||
.help = "Set log level for given tag",
|
||||
.hint = NULL,
|
||||
.func = &log_func,
|
||||
.argtable = &log_args,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||
}
|
||||
|
||||
void cmd_register_system(void)
|
||||
{
|
||||
register_version();
|
||||
register_heap();
|
||||
register_restart();
|
||||
register_reset();
|
||||
register_log();
|
||||
}
|
||||
580
esp-radar/console_test/components/commands/src/wifi_cmd.c
Normal file
580
esp-radar/console_test/components/commands/src/wifi_cmd.c
Normal file
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "nvs_flash.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#include "esp_mac.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_console.h"
|
||||
#include "esp_netif.h"
|
||||
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_DISCONNECTED_BIT BIT1
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
|
||||
#define ESP_IF_WIFI_STA ESP_MAC_WIFI_STA
|
||||
#endif
|
||||
|
||||
static bool s_reconnect = true;
|
||||
static const char *TAG = "wifi_cmd";
|
||||
|
||||
static EventGroupHandle_t s_wifi_event_group;
|
||||
|
||||
static bool mac_str2hex(const char *mac_str, uint8_t *mac_hex)
|
||||
{
|
||||
uint32_t mac_data[6] = {0};
|
||||
int ret = sscanf(mac_str, MACSTR, mac_data, mac_data + 1, mac_data + 2,
|
||||
mac_data + 3, mac_data + 4, mac_data + 5);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
mac_hex[i] = mac_data[i];
|
||||
}
|
||||
|
||||
return ret == 6 ? true : false;
|
||||
}
|
||||
|
||||
/* Event handler for catching system events */
|
||||
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
xEventGroupClearBits(s_wifi_event_group, WIFI_DISCONNECTED_BIT);
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
if (s_reconnect) {
|
||||
ESP_LOGI(TAG, "sta disconnect, s_reconnect...");
|
||||
esp_wifi_connect();
|
||||
} else {
|
||||
// ESP_LOGI(TAG, "sta disconnect");
|
||||
}
|
||||
|
||||
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_DISCONNECTED_BIT);
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
|
||||
wifi_event_sta_connected_t *event = (wifi_event_sta_connected_t *)event_data;
|
||||
ESP_LOGI(TAG, "Connected to %s (bssid: "MACSTR", channel: %d)", event->ssid,
|
||||
MAC2STR(event->bssid), event->channel);
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED) {
|
||||
ESP_LOGI(TAG, "STA Connecting to the AP again...");
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct arg_str *ssid;
|
||||
struct arg_str *password;
|
||||
struct arg_end *end;
|
||||
} wifi_args_t;
|
||||
|
||||
static wifi_args_t sta_args;
|
||||
static wifi_args_t ap_args;
|
||||
|
||||
static int wifi_cmd_sta(int argc, char **argv)
|
||||
{
|
||||
if (arg_parse(argc, argv, (void **) &sta_args) != ESP_OK) {
|
||||
arg_print_errors(stderr, sta_args.end, argv[0]);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
const char *ssid = sta_args.ssid->sval[0];
|
||||
const char *password = sta_args.password->sval[0];
|
||||
wifi_config_t wifi_config = { 0 };
|
||||
static esp_netif_t *s_netif_sta = NULL;
|
||||
|
||||
if (!s_wifi_event_group) {
|
||||
s_wifi_event_group = xEventGroupCreate();
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));
|
||||
}
|
||||
|
||||
if (!s_netif_sta) {
|
||||
// 检查是否已经存在默认的STA netif(可能由esp_radar_wifi_init创建)
|
||||
s_netif_sta = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
|
||||
if (!s_netif_sta) {
|
||||
s_netif_sta = esp_netif_create_default_wifi_sta();
|
||||
}
|
||||
}
|
||||
|
||||
strlcpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
|
||||
|
||||
if (password) {
|
||||
strlcpy((char *) wifi_config.sta.password, password, sizeof(wifi_config.sta.password));
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "sta connecting to '%s'", ssid);
|
||||
|
||||
int bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT, false, true, false);
|
||||
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
s_reconnect = false;
|
||||
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||
ESP_ERROR_CHECK(esp_wifi_disconnect());
|
||||
xEventGroupWaitBits(s_wifi_event_group, WIFI_DISCONNECTED_BIT, false, true, portMAX_DELAY);
|
||||
}
|
||||
|
||||
s_reconnect = true;
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
|
||||
esp_wifi_connect();
|
||||
|
||||
xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT, false, true, pdMS_TO_TICKS(5000));
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int wifi_cmd_ap(int argc, char **argv)
|
||||
{
|
||||
if (arg_parse(argc, argv, (void **) &ap_args) != ESP_OK) {
|
||||
arg_print_errors(stderr, ap_args.end, argv[0]);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
wifi_config_t wifi_config = {
|
||||
.ap = {
|
||||
.ssid = "",
|
||||
.ssid_len = 0,
|
||||
.max_connection = 4,
|
||||
.password = "",
|
||||
.channel = 11,
|
||||
},
|
||||
};
|
||||
|
||||
const char *ssid = ap_args.ssid->sval[0];
|
||||
const char *password = ap_args.password->sval[0];
|
||||
static esp_netif_t *s_netif_ap = NULL;
|
||||
|
||||
if (!s_wifi_event_group) {
|
||||
s_wifi_event_group = xEventGroupCreate();
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));
|
||||
}
|
||||
|
||||
if (!s_netif_ap) {
|
||||
s_netif_ap = esp_netif_create_default_wifi_ap();
|
||||
}
|
||||
|
||||
s_reconnect = false;
|
||||
strlcpy((char *) wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid));
|
||||
|
||||
if (password && strlen(password)) {
|
||||
if (strlen(password) < 8) {
|
||||
s_reconnect = true;
|
||||
ESP_LOGE(TAG, "password less than 8");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
|
||||
strlcpy((char *) wifi_config.ap.password, password, sizeof(wifi_config.ap.password));
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
|
||||
|
||||
ESP_LOGI(TAG, "Starting SoftAP SSID: %s, Password: %s", ssid, password);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int wifi_cmd_query(int argc, char **argv)
|
||||
{
|
||||
wifi_config_t cfg;
|
||||
wifi_mode_t mode;
|
||||
|
||||
esp_wifi_get_mode(&mode);
|
||||
|
||||
if (WIFI_MODE_AP == mode) {
|
||||
esp_wifi_get_config(WIFI_IF_AP, &cfg);
|
||||
ESP_LOGI(TAG, "AP mode, %s %s", cfg.ap.ssid, cfg.ap.password);
|
||||
} else if (WIFI_MODE_STA == mode) {
|
||||
int bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT, 0, 1, 0);
|
||||
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
esp_wifi_get_config(WIFI_IF_STA, &cfg);
|
||||
ESP_LOGI(TAG, "sta mode, connected %s", cfg.ap.ssid);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "sta mode, disconnected");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGI(TAG, "NULL mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cmd_register_wifi(void)
|
||||
{
|
||||
sta_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
|
||||
sta_args.password = arg_str0(NULL, NULL, "<password>", "password of AP");
|
||||
sta_args.end = arg_end(2);
|
||||
|
||||
const esp_console_cmd_t sta_cmd = {
|
||||
.command = "sta",
|
||||
.help = "WiFi is station mode, join specified soft-AP",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_sta,
|
||||
.argtable = &sta_args
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&sta_cmd));
|
||||
|
||||
ap_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
|
||||
ap_args.password = arg_str0(NULL, NULL, "<password>", "password of AP");
|
||||
ap_args.end = arg_end(2);
|
||||
|
||||
const esp_console_cmd_t ap_cmd = {
|
||||
.command = "ap",
|
||||
.help = "AP mode, configure ssid and password",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_ap,
|
||||
.argtable = &ap_args
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&ap_cmd));
|
||||
|
||||
const esp_console_cmd_t query_cmd = {
|
||||
.command = "query",
|
||||
.help = "query WiFi info",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_query,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&query_cmd));
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct arg_str *country_code;
|
||||
struct arg_int *channel;
|
||||
struct arg_int *channel_second;
|
||||
struct arg_str *ssid;
|
||||
struct arg_str *bssid;
|
||||
struct arg_str *password;
|
||||
struct arg_lit *disconnect;
|
||||
struct arg_int *tx_power;
|
||||
struct arg_lit *info;
|
||||
struct arg_int *rate;
|
||||
struct arg_int *bandwidth;
|
||||
struct arg_int *protocol;
|
||||
struct arg_end *end;
|
||||
} wifi_config_args;
|
||||
|
||||
/**
|
||||
* @brief A function which implements wifi config command.
|
||||
*/
|
||||
static int wifi_config_func(int argc, char **argv)
|
||||
{
|
||||
if (arg_parse(argc, argv, (void **) &wifi_config_args) != ESP_OK) {
|
||||
arg_print_errors(stderr, wifi_config_args.end, argv[0]);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (!s_wifi_event_group) {
|
||||
s_wifi_event_group = xEventGroupCreate();
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));
|
||||
}
|
||||
|
||||
if (wifi_config_args.disconnect->count) {
|
||||
s_reconnect = false;
|
||||
esp_wifi_disconnect();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
wifi_config_t wifi_config = {0x0};
|
||||
esp_wifi_get_config(WIFI_IF_STA, &wifi_config);
|
||||
static esp_netif_t *s_netif_sta = NULL;
|
||||
|
||||
wifi_mode_t mode;
|
||||
esp_wifi_get_mode(&mode);
|
||||
|
||||
if (!s_netif_sta && mode != WIFI_MODE_STA) {
|
||||
// 检查是否已经存在默认的STA netif(可能由esp_radar_wifi_init创建)
|
||||
s_netif_sta = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
|
||||
if (!s_netif_sta) {
|
||||
s_netif_sta = esp_netif_create_default_wifi_sta();
|
||||
}
|
||||
}
|
||||
|
||||
if (wifi_config_args.ssid->count) {
|
||||
strcpy((char *)wifi_config.sta.ssid, wifi_config_args.ssid->sval[0]);
|
||||
}
|
||||
|
||||
if (wifi_config_args.password->count) {
|
||||
strcpy((char *)wifi_config.sta.password, wifi_config_args.password->sval[0]);
|
||||
}
|
||||
|
||||
if (wifi_config_args.bssid->count) {
|
||||
if (!mac_str2hex(wifi_config_args.bssid->sval[0], wifi_config.sta.bssid)) {
|
||||
ESP_LOGE(TAG, "The format of the address is incorrect. Please enter the format as xx:xx:xx:xx:xx:xx");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen((char *)wifi_config.sta.ssid)) {
|
||||
int bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT, false, true, false);
|
||||
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
s_reconnect = false;
|
||||
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||
ESP_ERROR_CHECK(esp_wifi_disconnect());
|
||||
xEventGroupWaitBits(s_wifi_event_group, WIFI_DISCONNECTED_BIT, false, true, portMAX_DELAY);
|
||||
}
|
||||
|
||||
s_reconnect = true;
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
// esp_err_t esp_wifi_internal_set_fix_rate(wifi_interface_t ifx, bool en, wifi_phy_rate_t rate);
|
||||
// esp_wifi_internal_set_fix_rate(ESP_IF_WIFI_STA, true, WIFI_PHY_RATE_48M);
|
||||
// ESP_LOGW(TAG, "------- <%s, %d> ------", __func__, __LINE__);
|
||||
|
||||
// ESP_ERROR_CHECK(esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT20));
|
||||
|
||||
// ESP_ERROR_CHECK(esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G));
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
esp_wifi_connect();
|
||||
xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT, false, true, pdMS_TO_TICKS(5000));
|
||||
}
|
||||
|
||||
if (wifi_config_args.country_code->count) {
|
||||
wifi_country_t country = {0};
|
||||
const char *country_code = wifi_config_args.country_code->sval[0];
|
||||
|
||||
if (!strcasecmp(country_code, "US")) {
|
||||
strcpy(country.cc, "US");
|
||||
country.schan = 1;
|
||||
country.nchan = 11;
|
||||
} else if (!strcasecmp(country_code, "JP")) {
|
||||
strcpy(country.cc, "JP");
|
||||
country.schan = 1;
|
||||
country.nchan = 14;
|
||||
} else if (!strcasecmp(country_code, "CN")) {
|
||||
strcpy(country.cc, "CN");
|
||||
country.schan = 1;
|
||||
country.nchan = 13;
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ret = esp_wifi_set_country(&country);
|
||||
}
|
||||
|
||||
if (wifi_config_args.channel->count) {
|
||||
wifi_config.sta.channel = wifi_config_args.channel->ival[0];
|
||||
wifi_second_chan_t second = WIFI_SECOND_CHAN_NONE;
|
||||
|
||||
if (wifi_config_args.channel_second->count < 3) {
|
||||
second = wifi_config_args.channel_second->ival[0];
|
||||
}
|
||||
|
||||
if (wifi_config.sta.channel > 0 && wifi_config.sta.channel <= 14) {
|
||||
ret = esp_wifi_set_channel(wifi_config.sta.channel, second);
|
||||
|
||||
if (ret == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Set Channel, channel: %d", wifi_config.sta.channel);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "<%s> esp_wifi_set_channel", esp_err_to_name(ret));
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (wifi_config_args.tx_power->count) {
|
||||
esp_wifi_set_max_tx_power(wifi_config_args.tx_power->ival[0]);
|
||||
}
|
||||
|
||||
if (wifi_config_args.info->count) {
|
||||
int8_t rx_power = 0;
|
||||
wifi_country_t country = {0};
|
||||
uint8_t primary = 0;
|
||||
wifi_second_chan_t second = 0;
|
||||
wifi_mode_t mode = 0;
|
||||
wifi_bandwidth_t bandwidth = 0;
|
||||
|
||||
esp_wifi_get_channel(&primary, &second);
|
||||
esp_wifi_get_max_tx_power(&rx_power);
|
||||
esp_wifi_get_country(&country);
|
||||
esp_wifi_get_mode(&mode);
|
||||
esp_wifi_get_bandwidth(mode - 1, &bandwidth);
|
||||
|
||||
country.cc[2] = '\0';
|
||||
ESP_LOGI(TAG, "tx_power: %d, country: %s, channel: %d/%d, mode: %d, bandwidth: %d",
|
||||
rx_power, country.cc, primary, second, mode, bandwidth);
|
||||
}
|
||||
|
||||
if (wifi_config_args.bandwidth->count) {
|
||||
ESP_ERROR_CHECK(esp_wifi_set_bandwidth(ESP_IF_WIFI_STA, wifi_config_args.bandwidth->ival[0]));
|
||||
}
|
||||
|
||||
if (wifi_config_args.rate->count) {
|
||||
extern esp_err_t esp_wifi_internal_set_fix_rate(wifi_interface_t ifx, bool en, wifi_phy_rate_t rate);
|
||||
ESP_ERROR_CHECK(esp_wifi_internal_set_fix_rate(ESP_IF_WIFI_STA, true, wifi_config_args.rate->ival[0]));
|
||||
}
|
||||
|
||||
if (wifi_config_args.protocol->count) {
|
||||
ESP_ERROR_CHECK(esp_wifi_set_protocol(ESP_IF_WIFI_STA, wifi_config_args.protocol->ival[0]));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register wifi config command.
|
||||
*/
|
||||
void cmd_register_wifi_config()
|
||||
{
|
||||
wifi_config_args.ssid = arg_str0("s", "ssid", "<ssid>", "SSID of router");
|
||||
wifi_config_args.password = arg_str0("p", "password", "<password>", "Password of router");
|
||||
wifi_config_args.bssid = arg_str0("b", "bssid", "<bssid (xx:xx:xx:xx:xx:xx)>", "BSSID of router");
|
||||
wifi_config_args.disconnect = arg_lit0("d", "disconnect", "Disconnect the router");
|
||||
wifi_config_args.channel = arg_int0("c", "channel", "<channel (1 ~ 14)>", "Set primary channel");
|
||||
wifi_config_args.channel_second = arg_int0("c", "channel_second", "<channel_second (0, 1, 2)>", "Set second channel");
|
||||
wifi_config_args.country_code = arg_str0("C", "country_code", "<country_code ('CN', 'JP, 'US')>", "Set the current country code");
|
||||
wifi_config_args.tx_power = arg_int0("t", "tx_power", "<power (8 ~ 84)>", "Set maximum transmitting power after WiFi start.");
|
||||
wifi_config_args.rate = arg_int0("r", "rate", "<MCS>", "Set the bandwidth of ESP32 specified interface");
|
||||
wifi_config_args.bandwidth = arg_int0("w", "bandwidth", "<bandwidth(1: HT20, 2: HT40)>", "Set the bandwidth of ESP32 specified interface");
|
||||
wifi_config_args.protocol = arg_int0("P", "protocol", "<bgn(1,3,7)>", "Set protocol type of specified interface");
|
||||
wifi_config_args.info = arg_lit0("i", "info", "Get Wi-Fi configuration information");
|
||||
wifi_config_args.end = arg_end(10);
|
||||
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "wifi_config",
|
||||
.help = "Set the configuration of the ESP32 STA",
|
||||
.hint = NULL,
|
||||
.func = &wifi_config_func,
|
||||
.argtable = &wifi_config_args,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct arg_int *rssi;
|
||||
struct arg_str *ssid;
|
||||
struct arg_str *bssid;
|
||||
struct arg_int *passive;
|
||||
struct arg_end *end;
|
||||
} wifi_scan_args;
|
||||
|
||||
/**
|
||||
* @brief A function which implements wifi scan command.
|
||||
*/
|
||||
static esp_err_t wifi_scan_func(int argc, char **argv)
|
||||
{
|
||||
if (arg_parse(argc, argv, (void **) &wifi_scan_args) != ESP_OK) {
|
||||
arg_print_errors(stderr, wifi_scan_args.end, argv[0]);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int8_t filter_rssi = -120;
|
||||
uint16_t ap_number = 0;
|
||||
uint8_t bssid[6] = {0x0};
|
||||
uint8_t channel = 1;
|
||||
wifi_second_chan_t second = 0;
|
||||
wifi_ap_record_t ap_record = {0x0};
|
||||
wifi_scan_config_t scan_config = {
|
||||
.show_hidden = true,
|
||||
.scan_type = WIFI_SCAN_TYPE_ACTIVE,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_get_channel(&channel, &second));
|
||||
ESP_ERROR_CHECK(esp_wifi_disconnect());
|
||||
|
||||
if (wifi_scan_args.passive->count) {
|
||||
scan_config.scan_type = WIFI_SCAN_TYPE_PASSIVE;
|
||||
scan_config.scan_time.passive = wifi_scan_args.passive->ival[0];
|
||||
}
|
||||
|
||||
if (wifi_scan_args.ssid->count) {
|
||||
scan_config.ssid = (uint8_t *)wifi_scan_args.ssid->sval[0];
|
||||
}
|
||||
|
||||
if (wifi_scan_args.bssid->count) {
|
||||
if (!mac_str2hex(wifi_scan_args.bssid->sval[0], bssid)) {
|
||||
ESP_LOGE(TAG, "The format of the address is incorrect. Please enter the format as xx:xx:xx:xx:xx:xx");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
scan_config.bssid = bssid;
|
||||
}
|
||||
|
||||
if (wifi_scan_args.rssi->count) {
|
||||
filter_rssi = wifi_scan_args.rssi->ival[0];
|
||||
ESP_LOGW(TAG, "filter_rssi: %d", filter_rssi);
|
||||
}
|
||||
|
||||
esp_wifi_scan_stop();
|
||||
|
||||
int retry_count = 20;
|
||||
|
||||
do {
|
||||
esp_wifi_disconnect();
|
||||
esp_wifi_scan_start(&scan_config, true);
|
||||
esp_wifi_scan_get_ap_num(&ap_number);
|
||||
} while (ap_number <= 0 && --retry_count);
|
||||
|
||||
if (ap_number <= 0) {
|
||||
ESP_LOGE(TAG, "esp_wifi_scan_get_ap_num");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Get number of APs found, number: %d", ap_number);
|
||||
|
||||
for (int i = 0; i < ap_number; i++) {
|
||||
memset(&ap_record, 0, sizeof(wifi_ap_record_t));
|
||||
|
||||
if (ap_record.rssi < filter_rssi) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Router, ssid: %s, bssid: " MACSTR ", channel: %u, rssi: %d",
|
||||
ap_record.ssid, MAC2STR(ap_record.bssid),
|
||||
ap_record.primary, ap_record.rssi);
|
||||
}
|
||||
|
||||
if (channel > 0 && channel < 13) {
|
||||
ESP_ERROR_CHECK(esp_wifi_set_channel(channel, second));
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register wifi scan command.
|
||||
*/
|
||||
void cmd_register_wifi_scan()
|
||||
{
|
||||
wifi_scan_args.rssi = arg_int0("r", "rssi", "<rssi (-120 ~ 0)>", "Filter device uses RSSI");
|
||||
wifi_scan_args.ssid = arg_str0("s", "ssid", "<ssid>", "Filter device uses SSID");
|
||||
wifi_scan_args.bssid = arg_str0("b", "bssid", "<bssid (xx:xx:xx:xx:xx:xx)>", "Filter device uses AP's MAC");
|
||||
wifi_scan_args.passive = arg_int0("p", "passive", "<time (ms)>", "Passive scan time per channel");
|
||||
wifi_scan_args.end = arg_end(5);
|
||||
|
||||
const esp_console_cmd_t cmd = {
|
||||
.command = "wifi_scan",
|
||||
.help = "Wi-Fi is station mode, start scan ap",
|
||||
.hint = NULL,
|
||||
.func = &wifi_scan_func,
|
||||
.argtable = &wifi_scan_args,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||
}
|
||||
10
esp-radar/console_test/esp_csi_tool_gui.py
Normal file
10
esp-radar/console_test/esp_csi_tool_gui.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'esp_csi_tool_gui.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.6
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
3
esp-radar/console_test/main/CMakeLists.txt
Normal file
3
esp-radar/console_test/main/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
INCLUDE_DIRS ".")
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
16
esp-radar/console_test/main/Kconfig.projbuild
Normal file
16
esp-radar/console_test/main/Kconfig.projbuild
Normal file
@@ -0,0 +1,16 @@
|
||||
menu "WiFi Sensing Device Config"
|
||||
|
||||
config DEVICE_NAME
|
||||
string "Device Name"
|
||||
default "esp32-sensor"
|
||||
help
|
||||
Human-readable name for this ESP32 sensor device.
|
||||
This name will be included in CSI_DATA packets.
|
||||
|
||||
config DEVICE_LOCATION
|
||||
string "Device Location"
|
||||
default "room1"
|
||||
help
|
||||
Location identifier for this device (e.g., "living_room", "bedroom").
|
||||
|
||||
endmenu
|
||||
730
esp-radar/console_test/main/app_main.c
Normal file
730
esp-radar/console_test/main/app_main.c
Normal file
@@ -0,0 +1,730 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* Wi-Fi CSI console Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_console.h"
|
||||
|
||||
#include "esp_mac.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "ping/ping_sock.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "mbedtls/base64.h"
|
||||
|
||||
#include "led_strip.h"
|
||||
#include "esp_radar.h"
|
||||
#include "csi_commands.h"
|
||||
|
||||
extern esp_ping_handle_t g_ping_handle;
|
||||
static led_strip_handle_t led_strip;
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
#define WS2812_GPIO 27
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61
|
||||
#define WS2812_GPIO 8
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define WS2812_GPIO 38
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define WS2812_GPIO 18
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define WS2812_GPIO 8
|
||||
#else
|
||||
#define WS2812_GPIO 4
|
||||
#endif
|
||||
#define RECV_ESPNOW_CSI
|
||||
#define CONFIG_LESS_INTERFERENCE_CHANNEL 11
|
||||
#define CONFIG_SEND_DATA_FREQUENCY 100
|
||||
|
||||
#define RADAR_EVALUATE_SERVER_PORT 3232
|
||||
#define RADAR_BUFF_MAX_LEN 25
|
||||
|
||||
static QueueHandle_t g_csi_info_queue = NULL;
|
||||
static bool g_wifi_connect_status = false;
|
||||
static uint32_t g_send_data_interval = 1000 / CONFIG_SEND_DATA_FREQUENCY;
|
||||
static const char *TAG = "app_main";
|
||||
|
||||
static struct {
|
||||
struct arg_lit *train_start;
|
||||
struct arg_lit *train_stop;
|
||||
struct arg_lit *train_add;
|
||||
struct arg_str *predict_someone_threshold;
|
||||
struct arg_str *predict_someone_sensitivity;
|
||||
struct arg_str *predict_move_threshold;
|
||||
struct arg_str *predict_move_sensitivity;
|
||||
struct arg_int *predict_buff_size;
|
||||
struct arg_int *predict_outliers_number;
|
||||
struct arg_str *collect_taget;
|
||||
struct arg_int *collect_number;
|
||||
struct arg_int *collect_duration;
|
||||
struct arg_lit *csi_start;
|
||||
struct arg_lit *csi_stop;
|
||||
struct arg_str *csi_output_type;
|
||||
struct arg_str *csi_output_format;
|
||||
struct arg_int *csi_scale_shift;
|
||||
struct arg_int *channel_filter;
|
||||
struct arg_int *send_data_interval;
|
||||
struct arg_end *end;
|
||||
} radar_args;
|
||||
static struct console_input_config {
|
||||
bool train_start;
|
||||
float predict_someone_threshold;
|
||||
float predict_someone_sensitivity;
|
||||
float predict_move_threshold;
|
||||
float predict_move_sensitivity;
|
||||
uint32_t predict_buff_size;
|
||||
uint32_t predict_outliers_number;
|
||||
char collect_taget[16];
|
||||
uint32_t collect_number;
|
||||
char csi_output_type[16];
|
||||
char csi_output_format[16];
|
||||
} g_console_input_config = {
|
||||
.predict_someone_threshold = 0,
|
||||
.predict_someone_sensitivity = 0.15,
|
||||
.predict_move_threshold = 0.0003,
|
||||
.predict_move_sensitivity = 0.20,
|
||||
.predict_buff_size = 5,
|
||||
.predict_outliers_number = 2,
|
||||
.train_start = false,
|
||||
.collect_taget = "unknown",
|
||||
.csi_output_type = "LLTF",
|
||||
.csi_output_format = "decimal"
|
||||
};
|
||||
|
||||
static TimerHandle_t g_collect_timer_handele = NULL;
|
||||
|
||||
void wifi_csi_raw_cb(void *ctx, const wifi_csi_filtered_info_t *info)
|
||||
{
|
||||
wifi_csi_filtered_info_t *q_data = malloc(sizeof(wifi_csi_filtered_info_t) + info->valid_len);
|
||||
*q_data = *info;
|
||||
memcpy(q_data->valid_data, info->valid_data, info->valid_len);
|
||||
|
||||
if (!g_csi_info_queue || xQueueSend(g_csi_info_queue, &q_data, 0) == pdFALSE) {
|
||||
ESP_LOGW(TAG, "g_csi_info_queue full");
|
||||
free(q_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_timercb(TimerHandle_t timer)
|
||||
{
|
||||
g_console_input_config.collect_number--;
|
||||
|
||||
if (!g_console_input_config.collect_number) {
|
||||
xTimerStop(g_collect_timer_handele, 0);
|
||||
xTimerDelete(g_collect_timer_handele, 0);
|
||||
g_collect_timer_handele = NULL;
|
||||
strcpy(g_console_input_config.collect_taget, "unknown");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int wifi_cmd_radar(int argc, char **argv)
|
||||
{
|
||||
if (arg_parse(argc, argv, (void **) &radar_args) != ESP_OK) {
|
||||
arg_print_errors(stderr, radar_args.end, argv[0]);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (radar_args.train_start->count) {
|
||||
if (!radar_args.train_add->count) {
|
||||
esp_radar_train_remove();
|
||||
}
|
||||
|
||||
esp_radar_train_start();
|
||||
g_console_input_config.train_start = true;
|
||||
}
|
||||
|
||||
if (radar_args.train_stop->count) {
|
||||
esp_radar_train_stop(&g_console_input_config.predict_someone_threshold,
|
||||
&g_console_input_config.predict_move_threshold);
|
||||
g_console_input_config.train_start = false;
|
||||
|
||||
printf("RADAR_DADA,0,0,0,%.6f,0,0,%.6f,0\n",
|
||||
g_console_input_config.predict_someone_threshold,
|
||||
g_console_input_config.predict_move_threshold);
|
||||
}
|
||||
|
||||
if (radar_args.predict_move_threshold->count) {
|
||||
g_console_input_config.predict_move_threshold = atof(radar_args.predict_move_threshold->sval[0]);
|
||||
}
|
||||
|
||||
if (radar_args.predict_move_sensitivity->count) {
|
||||
g_console_input_config.predict_move_sensitivity = atof(radar_args.predict_move_sensitivity->sval[0]);
|
||||
ESP_LOGI(TAG, "predict_move_sensitivity: %f", g_console_input_config.predict_move_sensitivity);
|
||||
}
|
||||
|
||||
if (radar_args.predict_someone_threshold->count) {
|
||||
g_console_input_config.predict_someone_threshold = atof(radar_args.predict_someone_threshold->sval[0]);
|
||||
}
|
||||
|
||||
if (radar_args.predict_someone_sensitivity->count) {
|
||||
g_console_input_config.predict_someone_sensitivity = atof(radar_args.predict_someone_sensitivity->sval[0]);
|
||||
ESP_LOGI(TAG, "predict_someone_sensitivity: %f", g_console_input_config.predict_someone_sensitivity);
|
||||
}
|
||||
|
||||
if (radar_args.predict_buff_size->count) {
|
||||
g_console_input_config.predict_buff_size = radar_args.predict_buff_size->ival[0];
|
||||
}
|
||||
|
||||
if (radar_args.predict_outliers_number->count) {
|
||||
g_console_input_config.predict_outliers_number = radar_args.predict_outliers_number->ival[0];
|
||||
}
|
||||
|
||||
if (radar_args.collect_taget->count && radar_args.collect_number->count && radar_args.collect_duration->count) {
|
||||
g_console_input_config.collect_number = radar_args.collect_number->ival[0];
|
||||
strcpy(g_console_input_config.collect_taget, radar_args.collect_taget->sval[0]);
|
||||
|
||||
if (g_collect_timer_handele) {
|
||||
xTimerStop(g_collect_timer_handele, portMAX_DELAY);
|
||||
xTimerDelete(g_collect_timer_handele, portMAX_DELAY);
|
||||
}
|
||||
|
||||
g_collect_timer_handele = xTimerCreate("collect", pdMS_TO_TICKS(radar_args.collect_duration->ival[0]),
|
||||
true, NULL, collect_timercb);
|
||||
xTimerStart(g_collect_timer_handele, portMAX_DELAY);
|
||||
}
|
||||
|
||||
if (radar_args.csi_output_format->count) {
|
||||
strcpy(g_console_input_config.csi_output_format, radar_args.csi_output_format->sval[0]);
|
||||
}
|
||||
|
||||
if (radar_args.csi_output_type->count) {
|
||||
esp_radar_config_t radar_config = {0};
|
||||
esp_radar_get_config(&radar_config);
|
||||
|
||||
if (!strcasecmp(radar_args.csi_output_type->sval[0], "NULL")) {
|
||||
radar_config.csi_config.csi_filtered_cb = NULL;
|
||||
} else {
|
||||
radar_config.csi_config.csi_filtered_cb = wifi_csi_raw_cb;
|
||||
strcpy(g_console_input_config.csi_output_type, radar_args.csi_output_type->sval[0]);
|
||||
#if CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61
|
||||
if (!strcasecmp(radar_args.csi_output_type->sval[0], "LLTF")) {
|
||||
radar_config.csi_config.acquire_csi_lltf = true;
|
||||
radar_config.dec_config.ltf_type = RADAR_LTF_TYPE_LLTF;
|
||||
radar_config.dec_config.sub_carrier_step_size = 2;
|
||||
} else if (!strcasecmp(radar_args.csi_output_type->sval[0], "HT-LTF")) {
|
||||
radar_config.csi_config.acquire_csi_lltf = false;
|
||||
radar_config.csi_config.acquire_csi_ht20 = true;
|
||||
radar_config.csi_config.acquire_csi_ht40 = true;
|
||||
radar_config.csi_config.acquire_csi_vht = true;
|
||||
radar_config.dec_config.ltf_type = RADAR_LTF_TYPE_HTLTF;
|
||||
radar_config.dec_config.sub_carrier_step_size = 5;
|
||||
} else if (!strcasecmp(radar_args.csi_output_type->sval[0], "STBC-HT-LTF")) {
|
||||
radar_config.csi_config.acquire_csi_lltf = false;
|
||||
radar_config.csi_config.acquire_csi_ht20 = true;
|
||||
radar_config.csi_config.acquire_csi_ht40 = true;
|
||||
radar_config.csi_config.acquire_csi_vht = true;
|
||||
radar_config.dec_config.ltf_type = RADAR_LTF_TYPE_STBC_HTLTF;
|
||||
radar_config.dec_config.sub_carrier_step_size = 5;
|
||||
} else if (!strcasecmp(radar_args.csi_output_type->sval[0], "HE-LTF")) {
|
||||
radar_config.csi_config.acquire_csi_lltf = false;
|
||||
radar_config.csi_config.acquire_csi_su = true;
|
||||
radar_config.csi_config.acquire_csi_mu = true;
|
||||
radar_config.csi_config.acquire_csi_dcm = true;
|
||||
radar_config.csi_config.acquire_csi_beamformed = true;
|
||||
radar_config.csi_config.acquire_csi_vht = true;
|
||||
radar_config.dec_config.ltf_type = RADAR_LTF_TYPE_HELTF;
|
||||
radar_config.dec_config.sub_carrier_step_size = 5;
|
||||
} else if (!strcasecmp(radar_args.csi_output_type->sval[0], "STBC-HE-LTF")) {
|
||||
radar_config.csi_config.acquire_csi_lltf = false;
|
||||
radar_config.csi_config.acquire_csi_su = true;
|
||||
radar_config.csi_config.acquire_csi_mu = true;
|
||||
radar_config.csi_config.acquire_csi_dcm = true;
|
||||
radar_config.csi_config.acquire_csi_beamformed = true;
|
||||
radar_config.csi_config.acquire_csi_he_stbc_mode = CSI_HE_STBC_MODE_AVERAGE;
|
||||
radar_config.csi_config.acquire_csi_vht = true;
|
||||
radar_config.dec_config.ltf_type = RADAR_LTF_TYPE_STBC_HELTF;
|
||||
radar_config.dec_config.sub_carrier_step_size = 5;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_radar_change_config(&radar_config);
|
||||
}
|
||||
|
||||
if (radar_args.csi_start->count) {
|
||||
esp_radar_start();
|
||||
}
|
||||
|
||||
if (radar_args.csi_stop->count) {
|
||||
esp_radar_stop();
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32
|
||||
if (radar_args.csi_scale_shift->count) {
|
||||
esp_radar_config_t radar_config = {0};
|
||||
esp_radar_get_config(&radar_config);
|
||||
radar_config.csi_config.shift = radar_args.csi_scale_shift->ival[0];
|
||||
esp_radar_change_config(&radar_config);
|
||||
|
||||
ESP_LOGI(TAG, "manually left shift %d bits of the scale of the CSI data", radar_config.csi_config.shift);
|
||||
}
|
||||
|
||||
if (radar_args.channel_filter->count) {
|
||||
esp_radar_config_t radar_config = {0};
|
||||
esp_radar_get_config(&radar_config);
|
||||
radar_config.csi_config.channel_filter_en = radar_args.channel_filter->ival[0];
|
||||
esp_radar_change_config(&radar_config);
|
||||
|
||||
ESP_LOGI(TAG, "enable(%d) to turn on channel filter to smooth adjacent sub-carrier", radar_config.csi_config.channel_filter_en);
|
||||
}
|
||||
#endif
|
||||
if (radar_args.send_data_interval->count) {
|
||||
g_send_data_interval = radar_args.send_data_interval->ival[0];
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void cmd_register_radar(void)
|
||||
{
|
||||
radar_args.train_start = arg_lit0(NULL, "train_start", "Start calibrating the 'Radar' algorithm");
|
||||
radar_args.train_stop = arg_lit0(NULL, "train_stop", "Stop calibrating the 'Radar' algorithm");
|
||||
radar_args.train_add = arg_lit0(NULL, "train_add", "Calibrate on the basis of saving the calibration results");
|
||||
|
||||
radar_args.predict_someone_threshold = arg_str0(NULL, "predict_someone_threshold", "<0 ~ 1.0>", "Configure the threshold for someone");
|
||||
radar_args.predict_someone_sensitivity = arg_str0(NULL, "predict_someone_sensitivity", "<0 ~ 1.0>", "Configure the sensitivity for someone");
|
||||
radar_args.predict_move_threshold = arg_str0(NULL, "predict_move_threshold", "<0 ~ 1.0>", "Configure the threshold for move");
|
||||
radar_args.predict_move_sensitivity = arg_str0(NULL, "predict_move_sensitivity", "<0 ~ 1.0>", "Configure the sensitivity for move");
|
||||
radar_args.predict_buff_size = arg_int0(NULL, "predict_buff_size", "1 ~ 100", "Buffer size for filtering outliers");
|
||||
radar_args.predict_outliers_number = arg_int0(NULL, "predict_outliers_number", "<1 ~ 100>", "The number of items in the buffer queue greater than the threshold");
|
||||
|
||||
radar_args.collect_taget = arg_str0(NULL, "collect_tagets", "<0 ~ 20>", "Type of CSI data collected");
|
||||
radar_args.collect_number = arg_int0(NULL, "collect_number", "sequence", "Number of times CSI data was collected");
|
||||
radar_args.collect_duration = arg_int0(NULL, "collect_duration", "duration", "Time taken to acquire one CSI data");
|
||||
|
||||
radar_args.csi_start = arg_lit0(NULL, "csi_start", "Start collecting CSI data from Wi-Fi");
|
||||
radar_args.csi_stop = arg_lit0(NULL, "csi_stop", "Stop CSI data collection from Wi-Fi");
|
||||
radar_args.csi_output_type = arg_str0(NULL, "csi_output_type", "<NULL, LLTF, HT-LTF, HE-LTF, STBC-HT-LTF, STBC-HE-LTF>", "Type of CSI data");
|
||||
radar_args.csi_output_format = arg_str0(NULL, "csi_output_format", "<decimal, base64>", "Format of CSI data");
|
||||
radar_args.csi_scale_shift = arg_int0(NULL, "scale_shift", "<0~15>", "manually left shift bits of the scale of the CSI data");
|
||||
radar_args.channel_filter = arg_int0(NULL, "channel_filter", "<0 or 1>", "enable to turn on channel filter to smooth adjacent sub-carrier");
|
||||
|
||||
radar_args.send_data_interval = arg_int0(NULL, "send_data_interval", "<interval_ms>", "The interval between sending null data or ping packets to the router");
|
||||
|
||||
radar_args.end = arg_end(8);
|
||||
|
||||
const esp_console_cmd_t radar_cmd = {
|
||||
.command = "radar",
|
||||
.help = "Radar config",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_radar,
|
||||
.argtable = &radar_args
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&radar_cmd));
|
||||
}
|
||||
|
||||
static void csi_data_print_task(void *arg)
|
||||
{
|
||||
wifi_csi_filtered_info_t *info = NULL;
|
||||
char *buffer = malloc(8 * 1024);
|
||||
static uint32_t count = 0;
|
||||
|
||||
while (xQueueReceive(g_csi_info_queue, &info, portMAX_DELAY)) {
|
||||
size_t len = 0;
|
||||
esp_radar_rx_ctrl_info_t *rx_ctrl = &info->rx_ctrl_info;
|
||||
|
||||
if (!count) {
|
||||
ESP_LOGI(TAG, "================ CSI RECV ================");
|
||||
len += sprintf(buffer + len, "type,sequence,timestamp,taget_seq,target,mac,rssi,rate,sig_mode,mcs,bandwidth,smoothing,not_sounding,aggregation,stbc,fec_coding,sgi,noise_floor,ampdu_cnt,channel,secondary_channel,local_timestamp,ant,sig_len,rx_state,agc_gain,fft_gain,len,first_word,data\n");
|
||||
}
|
||||
uint16_t valid_len = info->valid_len;
|
||||
ESP_LOGI(TAG, "info->valid_len1: %d", info->valid_len);
|
||||
if (!strcasecmp(g_console_input_config.csi_output_type, "LLTF")) {
|
||||
info->valid_len = info->valid_lltf_len;
|
||||
} else if (!strcasecmp(g_console_input_config.csi_output_type, "HT-LTF")) {
|
||||
info->valid_len = info->valid_lltf_len + info->valid_ht_ltf_len;
|
||||
} else if (!strcasecmp(g_console_input_config.csi_output_type, "STBC-HT-LTF")) {
|
||||
info->valid_len = info->valid_lltf_len + info->valid_ht_ltf_len + info->valid_stbc_ht_ltf_len;
|
||||
#if CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61
|
||||
} else if (!strcasecmp(g_console_input_config.csi_output_type, "HE-LTF")) {
|
||||
info->valid_len = info->valid_he_ltf_len;
|
||||
} else if (!strcasecmp(g_console_input_config.csi_output_type, "STBC-HE-LTF")) {
|
||||
info->valid_len = info->valid_he_ltf_len + info->valid_stbc_he_ltf_len;
|
||||
#endif
|
||||
}
|
||||
ESP_LOGI(TAG, "info->valid_len: %d", info->valid_len);
|
||||
if (info->valid_len == 0) {
|
||||
info->valid_len = valid_len;
|
||||
|
||||
}
|
||||
len += sprintf(buffer + len, "CSI_DATA,%s,%s,%d,%u,%u,%s," MACSTR ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%u,%d,%d,%d,%d,%d,%d,%d,",
|
||||
CONFIG_DEVICE_NAME, CONFIG_DEVICE_LOCATION,
|
||||
count++, esp_log_timestamp(), g_console_input_config.collect_number, g_console_input_config.collect_taget,
|
||||
MAC2STR(info->mac), rx_ctrl->rssi, rx_ctrl->rate, rx_ctrl->signal_mode,
|
||||
rx_ctrl->mcs, rx_ctrl->cwb, 0, 0,
|
||||
0, rx_ctrl->stbc, 0, 0,
|
||||
rx_ctrl->noise_floor, 0, rx_ctrl->channel, rx_ctrl->secondary_channel,
|
||||
rx_ctrl->timestamp, 0, 0, 0, rx_ctrl->agc_gain, rx_ctrl->fft_gain, info->valid_len, 0);
|
||||
|
||||
if (!strcasecmp(g_console_input_config.csi_output_format, "base64")) {
|
||||
size_t size = 0;
|
||||
mbedtls_base64_encode((uint8_t *)buffer + len, sizeof(buffer) - len, &size, (uint8_t *)info->valid_data, info->valid_len);
|
||||
len += size;
|
||||
len += sprintf(buffer + len, "\n");
|
||||
} else {
|
||||
len += sprintf(buffer + len, "\"[%d", info->valid_data[0]);
|
||||
|
||||
for (int i = 1; i < info->valid_len; i++) {
|
||||
len += sprintf(buffer + len, ",%d", info->valid_data[i]);
|
||||
}
|
||||
|
||||
len += sprintf(buffer + len, "]\"\n");
|
||||
}
|
||||
|
||||
printf("%s", buffer);
|
||||
free(info);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void wifi_radar_cb(void *ctx, const wifi_radar_info_t *info)
|
||||
{
|
||||
static float *s_buff_wander = NULL;
|
||||
static float *s_buff_jitter = NULL;
|
||||
static uint32_t s_buff_count = 0;
|
||||
uint32_t buff_max_size = g_console_input_config.predict_buff_size;
|
||||
uint32_t buff_outliers_num = g_console_input_config.predict_outliers_number;
|
||||
uint32_t someone_count = 0;
|
||||
uint32_t move_count = 0;
|
||||
bool room_status = false;
|
||||
bool human_status = false;
|
||||
|
||||
if (!s_buff_wander) {
|
||||
s_buff_wander = calloc(RADAR_BUFF_MAX_LEN, sizeof(float));
|
||||
}
|
||||
|
||||
if (!s_buff_jitter) {
|
||||
s_buff_jitter = calloc(RADAR_BUFF_MAX_LEN, sizeof(float));
|
||||
}
|
||||
|
||||
s_buff_wander[s_buff_count % RADAR_BUFF_MAX_LEN] = info->waveform_wander;
|
||||
s_buff_jitter[s_buff_count % RADAR_BUFF_MAX_LEN] = info->waveform_jitter;
|
||||
s_buff_count++;
|
||||
|
||||
if (s_buff_count < buff_max_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
extern float trimmean(const float * array, size_t len, float percent);
|
||||
extern float median(const float * a, size_t len);
|
||||
|
||||
float wander_average = trimmean(s_buff_wander, RADAR_BUFF_MAX_LEN, 0.5);
|
||||
float jitter_midean = median(s_buff_jitter, RADAR_BUFF_MAX_LEN);
|
||||
|
||||
for (int i = 0; i < buff_max_size; i++) {
|
||||
uint32_t index = (s_buff_count - 1 - i) % RADAR_BUFF_MAX_LEN;
|
||||
|
||||
if ((wander_average * g_console_input_config.predict_someone_sensitivity > g_console_input_config.predict_someone_threshold)) {
|
||||
someone_count++;
|
||||
}
|
||||
|
||||
if (s_buff_jitter[index] * g_console_input_config.predict_move_sensitivity > g_console_input_config.predict_move_threshold
|
||||
|| (s_buff_jitter[index] * g_console_input_config.predict_move_sensitivity > jitter_midean && s_buff_jitter[index] > 0.0002)) {
|
||||
move_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (someone_count >= 1) {
|
||||
room_status = true;
|
||||
}
|
||||
|
||||
if (move_count >= buff_outliers_num) {
|
||||
human_status = true;
|
||||
}
|
||||
|
||||
static uint32_t s_count = 0;
|
||||
|
||||
if (!s_count) {
|
||||
ESP_LOGI(TAG, "================ RADAR RECV ================");
|
||||
ESP_LOGI(TAG, "type,sequence,timestamp,waveform_wander,someone_threshold,someone_status,waveform_jitter,move_threshold,move_status");
|
||||
}
|
||||
|
||||
char timestamp_str[32] = {0};
|
||||
sprintf(timestamp_str, "%u", esp_log_timestamp());
|
||||
|
||||
if (ctx) {
|
||||
strncpy(timestamp_str, (char *)ctx, 31);
|
||||
}
|
||||
|
||||
static uint32_t s_last_move_time = 0;
|
||||
static uint32_t s_last_someone_time = 0;
|
||||
|
||||
if (g_console_input_config.train_start) {
|
||||
s_last_move_time = esp_log_timestamp();
|
||||
s_last_someone_time = esp_log_timestamp();
|
||||
|
||||
static bool led_status = false;
|
||||
|
||||
if (led_status) {
|
||||
led_strip_set_pixel(led_strip, 0, 0, 0, 0);
|
||||
} else {
|
||||
led_strip_set_pixel(led_strip, 0, 255, 255, 0);
|
||||
}
|
||||
led_status = !led_status;
|
||||
led_strip_refresh(led_strip);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("RADAR_DADA,%d,%s,%.6f,%.6f,%.6f,%d,%.6f,%.6f,%.6f,%d\n",
|
||||
s_count++, timestamp_str,
|
||||
info->waveform_wander, wander_average, g_console_input_config.predict_someone_threshold / g_console_input_config.predict_someone_sensitivity, room_status,
|
||||
info->waveform_jitter, jitter_midean, jitter_midean / g_console_input_config.predict_move_sensitivity, human_status);
|
||||
|
||||
if (room_status) {
|
||||
if (human_status) {
|
||||
led_strip_set_pixel(led_strip, 0, 0, 255, 0);
|
||||
ESP_LOGI(TAG, "Someone moved");
|
||||
s_last_move_time = esp_log_timestamp();
|
||||
} else if (esp_log_timestamp() - s_last_move_time > 3 * 1000) {
|
||||
led_strip_set_pixel(led_strip, 0, 255, 255, 255);
|
||||
ESP_LOGI(TAG, "Someone");
|
||||
}
|
||||
|
||||
s_last_someone_time = esp_log_timestamp();
|
||||
} else if (esp_log_timestamp() - s_last_someone_time > 3 * 1000) {
|
||||
if (human_status) {
|
||||
s_last_move_time = esp_log_timestamp();
|
||||
led_strip_set_pixel(led_strip, 0, 255, 0, 0);
|
||||
} else if (esp_log_timestamp() - s_last_move_time > 3 * 1000) {
|
||||
led_strip_set_pixel(led_strip, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
led_strip_refresh(led_strip);
|
||||
}
|
||||
|
||||
static void trigger_router_send_data_task(void *arg)
|
||||
{
|
||||
esp_radar_config_t radar_config = {0};
|
||||
wifi_ap_record_t ap_info = {0};
|
||||
uint8_t sta_mac[6] = {0};
|
||||
|
||||
esp_radar_get_config(&radar_config);
|
||||
esp_wifi_sta_get_ap_info(&ap_info);
|
||||
ESP_ERROR_CHECK(esp_wifi_get_mac(WIFI_IF_STA, sta_mac));
|
||||
|
||||
radar_config.csi_config.csi_recv_interval = g_send_data_interval;
|
||||
memcpy(radar_config.csi_config.filter_dmac, sta_mac, sizeof(radar_config.csi_config.filter_dmac));
|
||||
|
||||
#if WIFI_CSI_SEND_NULL_DATA_ENABLE
|
||||
ESP_LOGI(TAG, "Send null data to router");
|
||||
|
||||
memset(radar_config.csi_config.filter_mac, 0, sizeof(radar_config.csi_config.filter_mac));
|
||||
esp_radar_change_config(&radar_config);
|
||||
|
||||
typedef struct {
|
||||
uint8_t frame_control[2];
|
||||
uint16_t duration;
|
||||
uint8_t destination_address[6];
|
||||
uint8_t source_address[6];
|
||||
uint8_t broadcast_address[6];
|
||||
uint16_t sequence_control;
|
||||
} __attribute__((packed)) wifi_null_data_t;
|
||||
|
||||
wifi_null_data_t null_data = {
|
||||
.frame_control = {0x48, 0x01},
|
||||
.duration = 0x0000,
|
||||
.sequence_control = 0x0000,
|
||||
};
|
||||
|
||||
memcpy(null_data.destination_address, ap_info.bssid, 6);
|
||||
memcpy(null_data.broadcast_address, ap_info.bssid, 6);
|
||||
memcpy(null_data.source_address, sta_mac, 6);
|
||||
|
||||
ESP_LOGW(TAG, "null_data, destination_address: "MACSTR", source_address: "MACSTR", broadcast_address: " MACSTR,
|
||||
MAC2STR(null_data.destination_address), MAC2STR(null_data.source_address), MAC2STR(null_data.broadcast_address));
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_config_80211_tx_rate(WIFI_IF_STA, WIFI_PHY_RATE_6M));
|
||||
|
||||
for (int i = 0; g_wifi_connect_status; i++) {
|
||||
esp_err_t ret = esp_wifi_80211_tx(WIFI_IF_STA, &null_data, sizeof(wifi_null_data_t), true);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGW(TAG, "esp_wifi_80211_tx, %s", esp_err_to_name(ret));
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(g_send_data_interval));
|
||||
}
|
||||
|
||||
#else
|
||||
ESP_LOGI(TAG, "Send ping data to router");
|
||||
|
||||
memcpy(radar_config.csi_config.filter_mac, ap_info.bssid, sizeof(radar_config.csi_config.filter_mac));
|
||||
esp_radar_change_config(&radar_config);
|
||||
|
||||
/* stop and delete existing ping session if any */
|
||||
if (g_ping_handle != NULL) {
|
||||
ESP_LOGI(TAG, "Stopping existing ping session before starting new one");
|
||||
esp_ping_stop(g_ping_handle);
|
||||
esp_ping_delete_session(g_ping_handle);
|
||||
g_ping_handle = NULL;
|
||||
ESP_LOGI(TAG, "Existing ping session stopped and deleted");
|
||||
}
|
||||
|
||||
esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
|
||||
config.count = 0;
|
||||
config.data_size = 1;
|
||||
config.interval_ms = g_send_data_interval;
|
||||
|
||||
/**
|
||||
* @brief Get the Router IP information from the esp-netif
|
||||
*/
|
||||
esp_netif_ip_info_t local_ip;
|
||||
esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &local_ip);
|
||||
ESP_LOGI(TAG, "Ping: got ip:" IPSTR ", gw: " IPSTR, IP2STR(&local_ip.ip), IP2STR(&local_ip.gw));
|
||||
config.target_addr.u_addr.ip4.addr = ip4_addr_get_u32(&local_ip.gw);
|
||||
config.target_addr.type = ESP_IPADDR_TYPE_V4;
|
||||
|
||||
esp_ping_callbacks_t cbs = { 0 };
|
||||
esp_ping_new_session(&config, &cbs, &g_ping_handle);
|
||||
esp_ping_start(g_ping_handle);
|
||||
#endif
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
/* Event handler for catching system events */
|
||||
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
g_wifi_connect_status = true;
|
||||
|
||||
xTaskCreate(trigger_router_send_data_task, "trigger_router_send_data", 4 * 1024, NULL, 5, NULL);
|
||||
|
||||
#ifdef RECV_ESPNOW_CSI
|
||||
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(false));
|
||||
#endif
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
g_wifi_connect_status = false;
|
||||
ESP_LOGW(TAG, "Wi-Fi disconnected");
|
||||
esp_radar_config_t radar_config;
|
||||
esp_radar_get_config(&radar_config);
|
||||
esp_radar_wifi_reinit(&radar_config.wifi_config);
|
||||
|
||||
}
|
||||
}
|
||||
esp_err_t ws2812_led_init(void)
|
||||
{
|
||||
led_strip_config_t strip_config = {
|
||||
.strip_gpio_num = WS2812_GPIO,
|
||||
.max_leds = 1,
|
||||
};
|
||||
|
||||
led_strip_rmt_config_t rmt_config = {
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption
|
||||
.resolution_hz = 10 * 1000 * 1000, // RMT counter clock frequency: 10MHz
|
||||
.flags = {
|
||||
.with_dma = false, // DMA feature is available on chips like ESP32-S3/P4
|
||||
}
|
||||
};
|
||||
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
||||
/* Set all LED off to clear all pixels */
|
||||
led_strip_clear(led_strip);
|
||||
return ESP_OK;
|
||||
}
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "app_main start, line: %d", __LINE__);
|
||||
/**
|
||||
* @brief Initialize NVS
|
||||
*/
|
||||
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(ret);
|
||||
ESP_LOGI(TAG, "app_main line: %d", __LINE__);
|
||||
/**
|
||||
* @brief Install ws2812 driver, Used to display the status of the device
|
||||
*/
|
||||
ws2812_led_init();
|
||||
|
||||
ESP_LOGI(TAG, "app_main start, line: %d", __LINE__);
|
||||
/**
|
||||
* @brief Turn on the radar module printing information
|
||||
*/
|
||||
esp_log_level_set("esp_radar", ESP_LOG_INFO);
|
||||
|
||||
/**
|
||||
* @brief Register serial command
|
||||
*/
|
||||
esp_console_repl_t *repl = NULL;
|
||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||
repl_config.prompt = "csi>";
|
||||
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||
/**< Fix serial port garbled code due to high baud rate */
|
||||
uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), UART_SCLK_APB);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE, APB_CLK_FREQ);
|
||||
#else
|
||||
uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set the Wi-Fi radar configuration
|
||||
*/
|
||||
esp_radar_csi_config_t csi_config = ESP_RADAR_CSI_CONFIG_DEFAULT();
|
||||
esp_radar_wifi_config_t wifi_config = ESP_RADAR_WIFI_CONFIG_DEFAULT();
|
||||
esp_radar_espnow_config_t espnow_config = ESP_RADAR_ESPNOW_CONFIG_DEFAULT();
|
||||
esp_radar_dec_config_t dec_config = ESP_RADAR_DEC_CONFIG_DEFAULT();
|
||||
memcpy(csi_config.filter_mac, "\x1a\x00\x00\x00\x00\x00", 6);
|
||||
csi_config.csi_recv_interval = g_send_data_interval;
|
||||
dec_config.wifi_radar_cb = wifi_radar_cb;
|
||||
#if WIFI_CSI_SEND_NULL_DATA_ENABLE
|
||||
csi_config.dump_ack_en = true;
|
||||
#endif
|
||||
dec_config.outliers_threshold = 0;
|
||||
ESP_ERROR_CHECK(esp_radar_wifi_init(&wifi_config));
|
||||
ESP_ERROR_CHECK(esp_radar_csi_init(&csi_config));
|
||||
ESP_ERROR_CHECK(esp_radar_dec_init(&dec_config));
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &wifi_event_handler, NULL));
|
||||
|
||||
cmd_register_ping();
|
||||
cmd_register_system();
|
||||
cmd_register_wifi_config();
|
||||
cmd_register_wifi_scan();
|
||||
cmd_register_radar();
|
||||
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
||||
|
||||
/**
|
||||
* @brief Start Wi-Fi radar
|
||||
*/
|
||||
esp_radar_start();
|
||||
|
||||
/**
|
||||
* @brief Initialize CSI serial port printing task, Use tasks to avoid blocking wifi_csi_raw_cb
|
||||
*/
|
||||
g_csi_info_queue = xQueueCreate(64, sizeof(void *));
|
||||
xTaskCreate(csi_data_print_task, "csi_data_print", 4 * 1024, NULL, 0, NULL);
|
||||
}
|
||||
7
esp-radar/console_test/main/idf_component.yml
Normal file
7
esp-radar/console_test/main/idf_component.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
idf: ">=4.4.1"
|
||||
|
||||
esp-radar: ">=0.3.0"
|
||||
|
||||
espressif/led_strip: "^2.5.3"
|
||||
255
esp-radar/console_test/main/radar_evaluate.c
Normal file
255
esp-radar/console_test/main/radar_evaluate.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* Wi-Fi CSI console Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_console.h"
|
||||
|
||||
#include "esp_wifi.h"
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#include "mbedtls/base64.h"
|
||||
#include "esp_radar.h"
|
||||
|
||||
#define RX_BUFFER_SIZE 1460
|
||||
#define KEEPALIVE_IDLE 1
|
||||
#define KEEPALIVE_INTERVAL 1
|
||||
#define KEEPALIVE_COUNT 3
|
||||
typedef union {
|
||||
struct {
|
||||
const char *type;
|
||||
const char *id;
|
||||
const char *timestamp;
|
||||
const char *action_id;
|
||||
const char *action;
|
||||
const char *mac;
|
||||
const char *rssi;
|
||||
const char *rate;
|
||||
const char *sig_mode;
|
||||
const char *mcs;
|
||||
const char *bandwidth;
|
||||
const char *smoothing;
|
||||
const char *not_sounding;
|
||||
const char *aggregation;
|
||||
const char *stbc;
|
||||
const char *fec_coding;
|
||||
const char *sgi;
|
||||
const char *noise_floor;
|
||||
const char *ampdu_cnt;
|
||||
const char *channel;
|
||||
const char *secondary_channel;
|
||||
const char *local_timestamp;
|
||||
const char *ant;
|
||||
const char *sig_len;
|
||||
const char *rx_state;
|
||||
const char *len;
|
||||
const char *first_word;
|
||||
const char *data;
|
||||
};
|
||||
const char *data_array[28];
|
||||
} csi_data_str_t;
|
||||
|
||||
static char *TAG = "radar_evaluate";
|
||||
static char g_wifi_radar_cb_ctx[32] = {0};
|
||||
static TaskHandle_t g_tcp_server_task_handle = NULL;
|
||||
|
||||
static void csi_info_analysis(char *data, size_t size)
|
||||
{
|
||||
uint8_t column = 0;
|
||||
const char *s = ",";
|
||||
char *token = NULL;
|
||||
csi_data_str_t *csi_data = malloc(sizeof(csi_data_str_t));
|
||||
|
||||
token = strtok(data, s);
|
||||
|
||||
do {
|
||||
csi_data->data_array[column++] = token;
|
||||
token = strtok(NULL, s);
|
||||
} while (token != NULL && column < 28);
|
||||
|
||||
if (token != NULL) {
|
||||
ESP_LOGE(TAG, "data error, temp_data: %s", data);
|
||||
}
|
||||
|
||||
wifi_csi_filtered_info_t *filtered_info = malloc(sizeof(wifi_csi_filtered_info_t) + 52 * 2);
|
||||
mbedtls_base64_decode((uint8_t *)filtered_info->valid_data, 52 * 2, (size_t *)&filtered_info->valid_len, (uint8_t *)csi_data->data, strlen(csi_data->data));
|
||||
filtered_info->rx_ctrl_info.timestamp = atoi(csi_data->local_timestamp);
|
||||
strcpy(g_wifi_radar_cb_ctx, csi_data->timestamp);
|
||||
// ESP_LOGI(TAG,"count: %s, timestamp: %d", csi_data->id, filtered_info->rx_ctrl.timestamp);
|
||||
|
||||
extern esp_err_t csi_data_push(wifi_csi_filtered_info_t *info);
|
||||
csi_data_push(filtered_info);
|
||||
|
||||
free(csi_data);
|
||||
}
|
||||
|
||||
static void tcp_server_task(void *arg)
|
||||
{
|
||||
char addr_str[128];
|
||||
int addr_family = AF_INET;
|
||||
int ip_protocol = 0;
|
||||
int keepAlive = 1;
|
||||
int keepIdle = KEEPALIVE_IDLE;
|
||||
int keepInterval = KEEPALIVE_INTERVAL;
|
||||
int keepCount = KEEPALIVE_COUNT;
|
||||
struct sockaddr_storage dest_addr;
|
||||
uint32_t port = (uint32_t)arg;
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr;
|
||||
dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
dest_addr_ip4->sin_family = AF_INET;
|
||||
dest_addr_ip4->sin_port = htons(port);
|
||||
ip_protocol = IPPROTO_IP;
|
||||
}
|
||||
|
||||
int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
|
||||
|
||||
if (listen_sock < 0) {
|
||||
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
int opt = 1;
|
||||
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
|
||||
ESP_LOGI(TAG, "Socket created");
|
||||
|
||||
int err = bind(listen_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
|
||||
|
||||
if (err != 0) {
|
||||
ESP_LOGE(TAG, "Socket unable to bind: errno %d, errno_str: %s", errno, strerror(errno));
|
||||
ESP_LOGE(TAG, "IPPROTO: %d", addr_family);
|
||||
goto CLEAN_UP;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Socket bound, port %d", port);
|
||||
|
||||
err = listen(listen_sock, 1);
|
||||
|
||||
if (err != 0) {
|
||||
ESP_LOGE(TAG, "Error occurred during listen: errno %d", errno);
|
||||
goto CLEAN_UP;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ESP_LOGI(TAG, "Socket listening");
|
||||
struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
|
||||
socklen_t addr_len = sizeof(source_addr);
|
||||
int sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
|
||||
|
||||
if (sock < 0) {
|
||||
ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
|
||||
break;
|
||||
}
|
||||
|
||||
// Set tcp keepalive option
|
||||
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(int));
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &keepIdle, sizeof(int));
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &keepInterval, sizeof(int));
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &keepCount, sizeof(int));
|
||||
|
||||
// Convert ip address to string
|
||||
if (source_addr.ss_family == PF_INET) {
|
||||
inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Socket accepted ip address: %s", addr_str);
|
||||
|
||||
int len;
|
||||
char *rx_buffer = malloc(RX_BUFFER_SIZE);
|
||||
size_t buf_size = 0;
|
||||
|
||||
esp_radar_config_t radar_config = {0};
|
||||
esp_radar_get_config(&radar_config);
|
||||
radar_config.dec_config.wifi_radar_cb_ctx = g_wifi_radar_cb_ctx;
|
||||
esp_radar_change_config(&radar_config);
|
||||
|
||||
do {
|
||||
len = recv(sock, rx_buffer + buf_size, RX_BUFFER_SIZE - buf_size - 1, 0);
|
||||
|
||||
// ESP_LOGW(TAG, "len: %d, rx_buffer: %s", len, rx_buffer);
|
||||
if (len < 0) {
|
||||
ESP_LOGE(TAG, "Error occurred during receiving: errno %d", errno);
|
||||
|
||||
} else if (len == 0) {
|
||||
ESP_LOGW(TAG, "Connection closed");
|
||||
} else {
|
||||
buf_size += len;
|
||||
rx_buffer[buf_size] = 0; // Null-terminate whatever is received and treat it like a string
|
||||
// ESP_LOGI(TAG, "Received %d, buf_size: %d", len, buf_size);
|
||||
|
||||
while (buf_size > 250) {
|
||||
char *begin = strstr(rx_buffer, "CSI_DATA");
|
||||
char *end = strstr(rx_buffer, "\n");
|
||||
ssize_t size = end - begin;
|
||||
|
||||
// ESP_LOGW("TAG", "begin: %p, end: %p, size: %d", begin, end, size);
|
||||
// ESP_LOGW(TAG, "size: %d, received: %d, buf_size: %d", size, len, buf_size);
|
||||
|
||||
if (begin && end && size > 250) {
|
||||
begin[size] = '\0';
|
||||
csi_info_analysis(begin, size);
|
||||
}
|
||||
|
||||
if (end) {
|
||||
buf_size -= (end + 1 - rx_buffer);
|
||||
memcpy(rx_buffer, end + 1, buf_size);
|
||||
memset(rx_buffer + buf_size, 0, end + 1 - rx_buffer);
|
||||
}
|
||||
|
||||
if (begin && !end) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (len > 0);
|
||||
|
||||
shutdown(sock, 0);
|
||||
close(sock);
|
||||
free(rx_buffer);
|
||||
|
||||
ESP_LOGW(TAG, "Socket close: %s", addr_str);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
esp_radar_get_config(&radar_config);
|
||||
radar_config.dec_config.wifi_radar_cb_ctx = NULL;
|
||||
esp_radar_change_config(&radar_config);
|
||||
}
|
||||
|
||||
CLEAN_UP:
|
||||
close(listen_sock);
|
||||
g_tcp_server_task_handle = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
esp_err_t radar_evaluate_server(uint32_t port)
|
||||
{
|
||||
if (!g_tcp_server_task_handle) {
|
||||
xTaskCreate(tcp_server_task, "tcp_server", 4 * 1024, (void *)port, 0, &g_tcp_server_task_handle);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
8
esp-radar/console_test/partitions.csv
Normal file
8
esp-radar/console_test/partitions.csv
Normal file
@@ -0,0 +1,8 @@
|
||||
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0xd000, 32K,
|
||||
fctry, data, nvs, 0x15000, 16K,
|
||||
log_status, data, nvs, 0x19000, 16K,
|
||||
otadata, data, ota, 0x1d000, 8K,
|
||||
phy_init, data, phy, 0x1f000, 4K,
|
||||
ota_0, app, ota_0, 0x20000, 1832K,
|
||||
|
53
esp-radar/console_test/sdkconfig.defaults
Normal file
53
esp-radar/console_test/sdkconfig.defaults
Normal file
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Serial flasher config
|
||||
#
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
CONFIG_ESPTOOLPY_BAUD_921600B=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB=y
|
||||
CONFIG_ESP_CONSOLE_UART_BAUDRATE=2000000
|
||||
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
|
||||
#
|
||||
# Wi-Fi
|
||||
#
|
||||
CONFIG_ESP32_WIFI_CSI_ENABLED=y
|
||||
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=
|
||||
|
||||
#
|
||||
# Common ESP-related
|
||||
#
|
||||
CONFIG_ESP_CONSOLE_UART_CUSTOM=y
|
||||
CONFIG_ESP_CONSOLE_UART=y
|
||||
CONFIG_ESP_CONSOLE_UART_NUM=0
|
||||
CONFIG_ESP_TASK_WDT_TIMEOUT_S=30
|
||||
|
||||
#
|
||||
# Compiler options
|
||||
#
|
||||
CONFIG_COMPILER_OPTIMIZATION_PERF=y
|
||||
|
||||
#
|
||||
# FreeRTOS
|
||||
#
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
|
||||
#
|
||||
# ESP32-specific
|
||||
#
|
||||
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
||||
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240
|
||||
|
||||
CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32
|
||||
|
||||
#
|
||||
# ESP32S3-specific
|
||||
#
|
||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
|
||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240
|
||||
1
esp-radar/console_test/tools/config/gui_config.json
Normal file
1
esp-radar/console_test/tools/config/gui_config.json
Normal file
@@ -0,0 +1 @@
|
||||
{"router_ssid": "Tplink_nyx", "router_password": "12345678", "router_auto_connect": false, "display_raw_data": true, "display_radar_model": true, "display_eigenvalues_table": false}
|
||||
1335
esp-radar/console_test/tools/esp_csi_tool.py
Executable file
1335
esp-radar/console_test/tools/esp_csi_tool.py
Executable file
File diff suppressed because it is too large
Load Diff
869
esp-radar/console_test/tools/esp_csi_tool_gui.py
Normal file
869
esp-radar/console_test/tools/esp_csi_tool_gui.py
Normal file
@@ -0,0 +1,869 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'esp_csi_tool_gui.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.10
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName("MainWindow")
|
||||
MainWindow.resize(1563, 850)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(14)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
MainWindow.setFont(font)
|
||||
MainWindow.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks|QtWidgets.QMainWindow.AnimatedDocks)
|
||||
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName("centralwidget")
|
||||
self.verticalLayout_17 = QtWidgets.QVBoxLayout(self.centralwidget)
|
||||
self.verticalLayout_17.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_17.setSpacing(0)
|
||||
self.verticalLayout_17.setObjectName("verticalLayout_17")
|
||||
self.horizontalLayout_11 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_11.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
|
||||
self.horizontalLayout_11.setSpacing(12)
|
||||
self.horizontalLayout_11.setObjectName("horizontalLayout_11")
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_11.addItem(spacerItem)
|
||||
self.label_2 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.horizontalLayout_11.addWidget(self.label_2)
|
||||
self.checkBox_raw_data = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.checkBox_raw_data.setChecked(True)
|
||||
self.checkBox_raw_data.setObjectName("checkBox_raw_data")
|
||||
self.horizontalLayout_11.addWidget(self.checkBox_raw_data)
|
||||
self.checkBox_radar_model = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.checkBox_radar_model.setChecked(True)
|
||||
self.checkBox_radar_model.setObjectName("checkBox_radar_model")
|
||||
self.horizontalLayout_11.addWidget(self.checkBox_radar_model)
|
||||
self.verticalLayout_17.addLayout(self.horizontalLayout_11)
|
||||
self.splitter_display = QtWidgets.QSplitter(self.centralwidget)
|
||||
self.splitter_display.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.splitter_display.setObjectName("splitter_display")
|
||||
self.groupBox_raw_data = QtWidgets.QGroupBox(self.splitter_display)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(14)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_raw_data.setFont(font)
|
||||
self.groupBox_raw_data.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.groupBox_raw_data.setObjectName("groupBox_raw_data")
|
||||
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.groupBox_raw_data)
|
||||
self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_6.setSpacing(0)
|
||||
self.verticalLayout_6.setObjectName("verticalLayout_6")
|
||||
self.splitter_raw_data = QtWidgets.QSplitter(self.groupBox_raw_data)
|
||||
self.splitter_raw_data.setOrientation(QtCore.Qt.Vertical)
|
||||
self.splitter_raw_data.setObjectName("splitter_raw_data")
|
||||
self.groupBox_16 = QtWidgets.QGroupBox(self.splitter_raw_data)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.groupBox_16.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox_16.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_16.setFont(font)
|
||||
self.groupBox_16.setObjectName("groupBox_16")
|
||||
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_16)
|
||||
self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_4.setSpacing(0)
|
||||
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
||||
self.groupBox_11 = QtWidgets.QGroupBox(self.groupBox_16)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.groupBox_11.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox_11.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_11.setFont(font)
|
||||
self.groupBox_11.setObjectName("groupBox_11")
|
||||
self.horizontalLayout_13 = QtWidgets.QHBoxLayout(self.groupBox_11)
|
||||
self.horizontalLayout_13.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_13.setSpacing(9)
|
||||
self.horizontalLayout_13.setObjectName("horizontalLayout_13")
|
||||
self.label_delay_2 = QtWidgets.QLabel(self.groupBox_11)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_delay_2.sizePolicy().hasHeightForWidth())
|
||||
self.label_delay_2.setSizePolicy(sizePolicy)
|
||||
self.label_delay_2.setObjectName("label_delay_2")
|
||||
self.horizontalLayout_13.addWidget(self.label_delay_2)
|
||||
self.lineEdit_router_ssid = QtWidgets.QLineEdit(self.groupBox_11)
|
||||
self.lineEdit_router_ssid.setObjectName("lineEdit_router_ssid")
|
||||
self.horizontalLayout_13.addWidget(self.lineEdit_router_ssid)
|
||||
self.label_duration_2 = QtWidgets.QLabel(self.groupBox_11)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_duration_2.sizePolicy().hasHeightForWidth())
|
||||
self.label_duration_2.setSizePolicy(sizePolicy)
|
||||
self.label_duration_2.setObjectName("label_duration_2")
|
||||
self.horizontalLayout_13.addWidget(self.label_duration_2)
|
||||
self.lineEdit_router_password = QtWidgets.QLineEdit(self.groupBox_11)
|
||||
self.lineEdit_router_password.setObjectName("lineEdit_router_password")
|
||||
self.horizontalLayout_13.addWidget(self.lineEdit_router_password)
|
||||
self.checkBox_router_auto_connect = QtWidgets.QCheckBox(self.groupBox_11)
|
||||
self.checkBox_router_auto_connect.setChecked(True)
|
||||
self.checkBox_router_auto_connect.setObjectName("checkBox_router_auto_connect")
|
||||
self.horizontalLayout_13.addWidget(self.checkBox_router_auto_connect)
|
||||
self.pushButton_router_connect = QtWidgets.QPushButton(self.groupBox_11)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(14)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.pushButton_router_connect.setFont(font)
|
||||
self.pushButton_router_connect.setAutoDefault(False)
|
||||
self.pushButton_router_connect.setDefault(False)
|
||||
self.pushButton_router_connect.setObjectName("pushButton_router_connect")
|
||||
self.horizontalLayout_13.addWidget(self.pushButton_router_connect)
|
||||
self.horizontalLayout_13.setStretch(0, 1)
|
||||
self.horizontalLayout_13.setStretch(1, 4)
|
||||
self.horizontalLayout_13.setStretch(2, 1)
|
||||
self.horizontalLayout_13.setStretch(3, 4)
|
||||
self.horizontalLayout_13.setStretch(4, 1)
|
||||
self.horizontalLayout_13.setStretch(5, 2)
|
||||
self.verticalLayout_4.addWidget(self.groupBox_11)
|
||||
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_4.setSpacing(0)
|
||||
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
|
||||
self.label = QtWidgets.QLabel(self.groupBox_16)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.label.setFont(font)
|
||||
self.label.setObjectName("label")
|
||||
self.horizontalLayout_4.addWidget(self.label)
|
||||
self.lineEdit_command = QtWidgets.QLineEdit(self.groupBox_16)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.lineEdit_command.setFont(font)
|
||||
self.lineEdit_command.setObjectName("lineEdit_command")
|
||||
self.horizontalLayout_4.addWidget(self.lineEdit_command)
|
||||
self.comboBox_command = QtWidgets.QComboBox(self.groupBox_16)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.comboBox_command.setFont(font)
|
||||
self.comboBox_command.setObjectName("comboBox_command")
|
||||
self.comboBox_command.addItem("")
|
||||
self.comboBox_command.addItem("")
|
||||
self.comboBox_command.addItem("")
|
||||
self.comboBox_command.addItem("")
|
||||
self.comboBox_command.addItem("")
|
||||
self.comboBox_command.addItem("")
|
||||
self.comboBox_command.addItem("")
|
||||
self.horizontalLayout_4.addWidget(self.comboBox_command)
|
||||
self.pushButton_command = QtWidgets.QPushButton(self.groupBox_16)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.pushButton_command.setFont(font)
|
||||
self.pushButton_command.setObjectName("pushButton_command")
|
||||
self.horizontalLayout_4.addWidget(self.pushButton_command)
|
||||
self.horizontalLayout_4.setStretch(0, 1)
|
||||
self.horizontalLayout_4.setStretch(1, 8)
|
||||
self.horizontalLayout_4.setStretch(2, 3)
|
||||
self.horizontalLayout_4.setStretch(3, 2)
|
||||
self.verticalLayout_4.addLayout(self.horizontalLayout_4)
|
||||
self.layoutWidget = QtWidgets.QWidget(self.splitter_raw_data)
|
||||
self.layoutWidget.setObjectName("layoutWidget")
|
||||
self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.layoutWidget)
|
||||
self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_7.setSpacing(0)
|
||||
self.verticalLayout_7.setObjectName("verticalLayout_7")
|
||||
self.groupBox_subcarrier = QtWidgets.QGroupBox(self.layoutWidget)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_subcarrier.setFont(font)
|
||||
self.groupBox_subcarrier.setFlat(False)
|
||||
self.groupBox_subcarrier.setCheckable(False)
|
||||
self.groupBox_subcarrier.setObjectName("groupBox_subcarrier")
|
||||
self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.groupBox_subcarrier)
|
||||
self.verticalLayout_9.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_9.setSpacing(0)
|
||||
self.verticalLayout_9.setObjectName("verticalLayout_9")
|
||||
self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_8.setObjectName("horizontalLayout_8")
|
||||
self.verticalLayout_9.addLayout(self.horizontalLayout_8)
|
||||
self.graphicsView_subcarrier = PlotWidget(self.groupBox_subcarrier)
|
||||
self.graphicsView_subcarrier.setObjectName("graphicsView_subcarrier")
|
||||
self.verticalLayout_9.addWidget(self.graphicsView_subcarrier)
|
||||
self.checkBox_wave_filtering = QtWidgets.QCheckBox(self.groupBox_subcarrier)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.checkBox_wave_filtering.setFont(font)
|
||||
self.checkBox_wave_filtering.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||
self.checkBox_wave_filtering.setChecked(True)
|
||||
self.checkBox_wave_filtering.setObjectName("checkBox_wave_filtering")
|
||||
self.verticalLayout_9.addWidget(self.checkBox_wave_filtering)
|
||||
self.verticalLayout_7.addWidget(self.groupBox_subcarrier)
|
||||
self.groupBox_rssi = QtWidgets.QGroupBox(self.layoutWidget)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_rssi.setFont(font)
|
||||
self.groupBox_rssi.setObjectName("groupBox_rssi")
|
||||
self.verticalLayout_10 = QtWidgets.QVBoxLayout(self.groupBox_rssi)
|
||||
self.verticalLayout_10.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_10.setSpacing(0)
|
||||
self.verticalLayout_10.setObjectName("verticalLayout_10")
|
||||
self.graphicsView_rssi = PlotWidget(self.groupBox_rssi)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.graphicsView_rssi.sizePolicy().hasHeightForWidth())
|
||||
self.graphicsView_rssi.setSizePolicy(sizePolicy)
|
||||
self.graphicsView_rssi.setObjectName("graphicsView_rssi")
|
||||
self.verticalLayout_10.addWidget(self.graphicsView_rssi)
|
||||
self.verticalLayout_7.addWidget(self.groupBox_rssi)
|
||||
self.verticalLayout_7.setStretch(0, 32)
|
||||
self.verticalLayout_7.setStretch(1, 1)
|
||||
self.groupBox_13 = QtWidgets.QGroupBox(self.splitter_raw_data)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_13.setFont(font)
|
||||
self.groupBox_13.setObjectName("groupBox_13")
|
||||
self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.groupBox_13)
|
||||
self.verticalLayout_13.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_13.setSpacing(0)
|
||||
self.verticalLayout_13.setObjectName("verticalLayout_13")
|
||||
self.textBrowser_log = QtWidgets.QTextBrowser(self.groupBox_13)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.textBrowser_log.sizePolicy().hasHeightForWidth())
|
||||
self.textBrowser_log.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.textBrowser_log.setFont(font)
|
||||
self.textBrowser_log.setObjectName("textBrowser_log")
|
||||
self.verticalLayout_13.addWidget(self.textBrowser_log)
|
||||
self.groupBox_radioHeader = QtWidgets.QGroupBox(self.groupBox_13)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_radioHeader.setFont(font)
|
||||
self.groupBox_radioHeader.setObjectName("groupBox_radioHeader")
|
||||
self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.groupBox_radioHeader)
|
||||
self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_5.setSpacing(0)
|
||||
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.tableView_radioHeader = QtWidgets.QTableView(self.groupBox_radioHeader)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.tableView_radioHeader.setFont(font)
|
||||
self.tableView_radioHeader.setAutoScrollMargin(10)
|
||||
self.tableView_radioHeader.setSortingEnabled(False)
|
||||
self.tableView_radioHeader.setObjectName("tableView_radioHeader")
|
||||
self.tableView_radioHeader.horizontalHeader().setMinimumSectionSize(12)
|
||||
self.tableView_radioHeader.verticalHeader().setDefaultSectionSize(20)
|
||||
self.tableView_radioHeader.verticalHeader().setMinimumSectionSize(10)
|
||||
self.tableView_radioHeader.verticalHeader().setStretchLastSection(True)
|
||||
self.horizontalLayout_5.addWidget(self.tableView_radioHeader)
|
||||
self.tableView_device_info = QtWidgets.QTableView(self.groupBox_radioHeader)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.tableView_device_info.setFont(font)
|
||||
self.tableView_device_info.setAutoScrollMargin(10)
|
||||
self.tableView_device_info.setSortingEnabled(False)
|
||||
self.tableView_device_info.setObjectName("tableView_device_info")
|
||||
self.tableView_device_info.horizontalHeader().setMinimumSectionSize(12)
|
||||
self.tableView_device_info.verticalHeader().setDefaultSectionSize(20)
|
||||
self.tableView_device_info.verticalHeader().setMinimumSectionSize(10)
|
||||
self.tableView_device_info.verticalHeader().setStretchLastSection(True)
|
||||
self.horizontalLayout_5.addWidget(self.tableView_device_info)
|
||||
self.horizontalLayout_5.setStretch(0, 5)
|
||||
self.horizontalLayout_5.setStretch(1, 2)
|
||||
self.verticalLayout_13.addWidget(self.groupBox_radioHeader)
|
||||
self.verticalLayout_13.setStretch(0, 16)
|
||||
self.verticalLayout_13.setStretch(1, 1)
|
||||
self.verticalLayout_6.addWidget(self.splitter_raw_data)
|
||||
self.groupBox_radar_model = QtWidgets.QGroupBox(self.splitter_display)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(14)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_radar_model.setFont(font)
|
||||
self.groupBox_radar_model.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.groupBox_radar_model.setObjectName("groupBox_radar_model")
|
||||
self.verticalLayout_18 = QtWidgets.QVBoxLayout(self.groupBox_radar_model)
|
||||
self.verticalLayout_18.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_18.setSpacing(0)
|
||||
self.verticalLayout_18.setObjectName("verticalLayout_18")
|
||||
self.splitter_3 = QtWidgets.QSplitter(self.groupBox_radar_model)
|
||||
self.splitter_3.setOrientation(QtCore.Qt.Vertical)
|
||||
self.splitter_3.setObjectName("splitter_3")
|
||||
self.layoutWidget1 = QtWidgets.QWidget(self.splitter_3)
|
||||
self.layoutWidget1.setObjectName("layoutWidget1")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget1)
|
||||
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_2.setSpacing(0)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.groupBox_15 = QtWidgets.QGroupBox(self.layoutWidget1)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_15.setFont(font)
|
||||
self.groupBox_15.setObjectName("groupBox_15")
|
||||
self.verticalLayout_25 = QtWidgets.QVBoxLayout(self.groupBox_15)
|
||||
self.verticalLayout_25.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_25.setSpacing(0)
|
||||
self.verticalLayout_25.setObjectName("verticalLayout_25")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setSpacing(9)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.widget_25 = QtWidgets.QWidget(self.groupBox_15)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.widget_25.sizePolicy().hasHeightForWidth())
|
||||
self.widget_25.setSizePolicy(sizePolicy)
|
||||
self.widget_25.setObjectName("widget_25")
|
||||
self.horizontalLayout_27 = QtWidgets.QHBoxLayout(self.widget_25)
|
||||
self.horizontalLayout_27.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_27.setSpacing(0)
|
||||
self.horizontalLayout_27.setObjectName("horizontalLayout_27")
|
||||
self.widget_39 = QtWidgets.QWidget(self.widget_25)
|
||||
self.widget_39.setObjectName("widget_39")
|
||||
self.horizontalLayout_38 = QtWidgets.QHBoxLayout(self.widget_39)
|
||||
self.horizontalLayout_38.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_38.setSpacing(0)
|
||||
self.horizontalLayout_38.setObjectName("horizontalLayout_38")
|
||||
self.horizontalLayout_27.addWidget(self.widget_39)
|
||||
self.label_delay_5 = QtWidgets.QLabel(self.widget_25)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_delay_5.sizePolicy().hasHeightForWidth())
|
||||
self.label_delay_5.setSizePolicy(sizePolicy)
|
||||
self.label_delay_5.setObjectName("label_delay_5")
|
||||
self.horizontalLayout_27.addWidget(self.label_delay_5)
|
||||
self.timeEdit_train_delay = QtWidgets.QTimeEdit(self.widget_25)
|
||||
self.timeEdit_train_delay.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2000, 1, 1), QtCore.QTime(23, 59, 59)))
|
||||
self.timeEdit_train_delay.setCurrentSection(QtWidgets.QDateTimeEdit.MinuteSection)
|
||||
self.timeEdit_train_delay.setCurrentSectionIndex(1)
|
||||
self.timeEdit_train_delay.setTime(QtCore.QTime(0, 0, 0))
|
||||
self.timeEdit_train_delay.setObjectName("timeEdit_train_delay")
|
||||
self.horizontalLayout_27.addWidget(self.timeEdit_train_delay)
|
||||
self.horizontalLayout_27.setStretch(1, 2)
|
||||
self.horizontalLayout_27.setStretch(2, 3)
|
||||
self.horizontalLayout_2.addWidget(self.widget_25)
|
||||
self.widget_26 = QtWidgets.QWidget(self.groupBox_15)
|
||||
self.widget_26.setObjectName("widget_26")
|
||||
self.horizontalLayout_28 = QtWidgets.QHBoxLayout(self.widget_26)
|
||||
self.horizontalLayout_28.setContentsMargins(9, 0, 0, 0)
|
||||
self.horizontalLayout_28.setSpacing(0)
|
||||
self.horizontalLayout_28.setObjectName("horizontalLayout_28")
|
||||
self.label_delay_6 = QtWidgets.QLabel(self.widget_26)
|
||||
self.label_delay_6.setObjectName("label_delay_6")
|
||||
self.horizontalLayout_28.addWidget(self.label_delay_6)
|
||||
self.timeEdit_train_duration = QtWidgets.QTimeEdit(self.widget_26)
|
||||
self.timeEdit_train_duration.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2000, 1, 1), QtCore.QTime(23, 59, 59)))
|
||||
self.timeEdit_train_duration.setCurrentSection(QtWidgets.QDateTimeEdit.SecondSection)
|
||||
self.timeEdit_train_duration.setCurrentSectionIndex(2)
|
||||
self.timeEdit_train_duration.setTime(QtCore.QTime(0, 0, 10))
|
||||
self.timeEdit_train_duration.setObjectName("timeEdit_train_duration")
|
||||
self.horizontalLayout_28.addWidget(self.timeEdit_train_duration)
|
||||
self.horizontalLayout_28.setStretch(0, 2)
|
||||
self.horizontalLayout_28.setStretch(1, 3)
|
||||
self.horizontalLayout_2.addWidget(self.widget_26)
|
||||
self.checkBox_train_add = QtWidgets.QCheckBox(self.groupBox_15)
|
||||
self.checkBox_train_add.setEnabled(True)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.checkBox_train_add.sizePolicy().hasHeightForWidth())
|
||||
self.checkBox_train_add.setSizePolicy(sizePolicy)
|
||||
self.checkBox_train_add.setObjectName("checkBox_train_add")
|
||||
self.horizontalLayout_2.addWidget(self.checkBox_train_add)
|
||||
self.pushButton_train_start = QtWidgets.QPushButton(self.groupBox_15)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(14)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.pushButton_train_start.setFont(font)
|
||||
self.pushButton_train_start.setIconSize(QtCore.QSize(8, 8))
|
||||
self.pushButton_train_start.setAutoDefault(False)
|
||||
self.pushButton_train_start.setDefault(False)
|
||||
self.pushButton_train_start.setObjectName("pushButton_train_start")
|
||||
self.horizontalLayout_2.addWidget(self.pushButton_train_start)
|
||||
self.horizontalLayout_2.setStretch(0, 1)
|
||||
self.horizontalLayout_2.setStretch(1, 1)
|
||||
self.horizontalLayout_2.setStretch(2, 1)
|
||||
self.horizontalLayout_2.setStretch(3, 1)
|
||||
self.verticalLayout_25.addLayout(self.horizontalLayout_2)
|
||||
self.verticalLayout_2.addWidget(self.groupBox_15)
|
||||
self.groupBox_14 = QtWidgets.QGroupBox(self.layoutWidget1)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_14.setFont(font)
|
||||
self.groupBox_14.setObjectName("groupBox_14")
|
||||
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_14)
|
||||
self.verticalLayout_5.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_5.setSpacing(0)
|
||||
self.verticalLayout_5.setObjectName("verticalLayout_5")
|
||||
self.horizontalLayout_10 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_10.setObjectName("horizontalLayout_10")
|
||||
self.widget_31 = QtWidgets.QWidget(self.groupBox_14)
|
||||
self.widget_31.setObjectName("widget_31")
|
||||
self.horizontalLayout_45 = QtWidgets.QHBoxLayout(self.widget_31)
|
||||
self.horizontalLayout_45.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_45.setSpacing(9)
|
||||
self.horizontalLayout_45.setObjectName("horizontalLayout_45")
|
||||
self.label_number_3 = QtWidgets.QLabel(self.widget_31)
|
||||
self.label_number_3.setObjectName("label_number_3")
|
||||
self.horizontalLayout_45.addWidget(self.label_number_3)
|
||||
self.doubleSpinBox_predict_someone_sensitivity = QtWidgets.QDoubleSpinBox(self.widget_31)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.doubleSpinBox_predict_someone_sensitivity.sizePolicy().hasHeightForWidth())
|
||||
self.doubleSpinBox_predict_someone_sensitivity.setSizePolicy(sizePolicy)
|
||||
self.doubleSpinBox_predict_someone_sensitivity.setDecimals(2)
|
||||
self.doubleSpinBox_predict_someone_sensitivity.setMinimum(0.01)
|
||||
self.doubleSpinBox_predict_someone_sensitivity.setMaximum(1.0)
|
||||
self.doubleSpinBox_predict_someone_sensitivity.setSingleStep(0.01)
|
||||
self.doubleSpinBox_predict_someone_sensitivity.setProperty("value", 0.2)
|
||||
self.doubleSpinBox_predict_someone_sensitivity.setObjectName("doubleSpinBox_predict_someone_sensitivity")
|
||||
self.horizontalLayout_45.addWidget(self.doubleSpinBox_predict_someone_sensitivity)
|
||||
self.label_number_5 = QtWidgets.QLabel(self.widget_31)
|
||||
self.label_number_5.setObjectName("label_number_5")
|
||||
self.horizontalLayout_45.addWidget(self.label_number_5)
|
||||
self.doubleSpinBox_predict_move_sensitivity = QtWidgets.QDoubleSpinBox(self.widget_31)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.doubleSpinBox_predict_move_sensitivity.sizePolicy().hasHeightForWidth())
|
||||
self.doubleSpinBox_predict_move_sensitivity.setSizePolicy(sizePolicy)
|
||||
self.doubleSpinBox_predict_move_sensitivity.setDecimals(2)
|
||||
self.doubleSpinBox_predict_move_sensitivity.setMinimum(0.01)
|
||||
self.doubleSpinBox_predict_move_sensitivity.setMaximum(1.0)
|
||||
self.doubleSpinBox_predict_move_sensitivity.setSingleStep(0.01)
|
||||
self.doubleSpinBox_predict_move_sensitivity.setProperty("value", 0.2)
|
||||
self.doubleSpinBox_predict_move_sensitivity.setObjectName("doubleSpinBox_predict_move_sensitivity")
|
||||
self.horizontalLayout_45.addWidget(self.doubleSpinBox_predict_move_sensitivity)
|
||||
self.label_duration_7 = QtWidgets.QLabel(self.widget_31)
|
||||
self.label_duration_7.setObjectName("label_duration_7")
|
||||
self.horizontalLayout_45.addWidget(self.label_duration_7)
|
||||
self.spinBox_predict_buffer_size = QtWidgets.QSpinBox(self.widget_31)
|
||||
self.spinBox_predict_buffer_size.setMinimum(1)
|
||||
self.spinBox_predict_buffer_size.setProperty("value", 5)
|
||||
self.spinBox_predict_buffer_size.setDisplayIntegerBase(10)
|
||||
self.spinBox_predict_buffer_size.setObjectName("spinBox_predict_buffer_size")
|
||||
self.horizontalLayout_45.addWidget(self.spinBox_predict_buffer_size)
|
||||
self.spinBox_predict_outliers_number = QtWidgets.QSpinBox(self.widget_31)
|
||||
self.spinBox_predict_outliers_number.setMinimum(1)
|
||||
self.spinBox_predict_outliers_number.setMaximum(99)
|
||||
self.spinBox_predict_outliers_number.setSingleStep(1)
|
||||
self.spinBox_predict_outliers_number.setProperty("value", 2)
|
||||
self.spinBox_predict_outliers_number.setDisplayIntegerBase(10)
|
||||
self.spinBox_predict_outliers_number.setObjectName("spinBox_predict_outliers_number")
|
||||
self.horizontalLayout_45.addWidget(self.spinBox_predict_outliers_number)
|
||||
self.checkBox_display_eigenvalues_table = QtWidgets.QCheckBox(self.widget_31)
|
||||
self.checkBox_display_eigenvalues_table.setObjectName("checkBox_display_eigenvalues_table")
|
||||
self.horizontalLayout_45.addWidget(self.checkBox_display_eigenvalues_table)
|
||||
self.pushButton_predict_config = QtWidgets.QPushButton(self.widget_31)
|
||||
self.pushButton_predict_config.setObjectName("pushButton_predict_config")
|
||||
self.horizontalLayout_45.addWidget(self.pushButton_predict_config)
|
||||
self.horizontalLayout_45.setStretch(0, 3)
|
||||
self.horizontalLayout_45.setStretch(1, 2)
|
||||
self.horizontalLayout_45.setStretch(2, 3)
|
||||
self.horizontalLayout_45.setStretch(3, 2)
|
||||
self.horizontalLayout_45.setStretch(4, 2)
|
||||
self.horizontalLayout_45.setStretch(5, 1)
|
||||
self.horizontalLayout_45.setStretch(6, 1)
|
||||
self.horizontalLayout_45.setStretch(7, 2)
|
||||
self.horizontalLayout_45.setStretch(8, 3)
|
||||
self.horizontalLayout_10.addWidget(self.widget_31)
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_10)
|
||||
self.splitter_eigenvalues = QtWidgets.QSplitter(self.groupBox_14)
|
||||
self.splitter_eigenvalues.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.splitter_eigenvalues.setObjectName("splitter_eigenvalues")
|
||||
self.graphicsView_eigenvalues = PlotWidget(self.splitter_eigenvalues)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.graphicsView_eigenvalues.sizePolicy().hasHeightForWidth())
|
||||
self.graphicsView_eigenvalues.setSizePolicy(sizePolicy)
|
||||
self.graphicsView_eigenvalues.setObjectName("graphicsView_eigenvalues")
|
||||
self.tableView_eigenvalues = QtWidgets.QWidget(self.splitter_eigenvalues)
|
||||
self.tableView_eigenvalues.setObjectName("tableView_eigenvalues")
|
||||
self.tableView_eigenvalues_QVBoxLayout = QtWidgets.QVBoxLayout(self.tableView_eigenvalues)
|
||||
self.tableView_eigenvalues_QVBoxLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.tableView_eigenvalues_QVBoxLayout.setSpacing(0)
|
||||
self.tableView_eigenvalues_QVBoxLayout.setObjectName("tableView_eigenvalues_QVBoxLayout")
|
||||
self.tableView_radar_data_room = QtWidgets.QTableView(self.tableView_eigenvalues)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.tableView_radar_data_room.setFont(font)
|
||||
self.tableView_radar_data_room.setAutoScrollMargin(10)
|
||||
self.tableView_radar_data_room.setSortingEnabled(False)
|
||||
self.tableView_radar_data_room.setObjectName("tableView_radar_data_room")
|
||||
self.tableView_radar_data_room.horizontalHeader().setMinimumSectionSize(12)
|
||||
self.tableView_radar_data_room.verticalHeader().setDefaultSectionSize(20)
|
||||
self.tableView_radar_data_room.verticalHeader().setMinimumSectionSize(10)
|
||||
self.tableView_radar_data_room.verticalHeader().setStretchLastSection(True)
|
||||
self.tableView_eigenvalues_QVBoxLayout.addWidget(self.tableView_radar_data_room)
|
||||
self.tableView_radar_data_human = QtWidgets.QTableView(self.tableView_eigenvalues)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.tableView_radar_data_human.setFont(font)
|
||||
self.tableView_radar_data_human.setAutoScrollMargin(10)
|
||||
self.tableView_radar_data_human.setSortingEnabled(False)
|
||||
self.tableView_radar_data_human.setObjectName("tableView_radar_data_human")
|
||||
self.tableView_radar_data_human.horizontalHeader().setMinimumSectionSize(12)
|
||||
self.tableView_radar_data_human.verticalHeader().setDefaultSectionSize(20)
|
||||
self.tableView_radar_data_human.verticalHeader().setMinimumSectionSize(10)
|
||||
self.tableView_radar_data_human.verticalHeader().setStretchLastSection(True)
|
||||
self.tableView_eigenvalues_QVBoxLayout.addWidget(self.tableView_radar_data_human)
|
||||
self.verticalLayout_5.addWidget(self.splitter_eigenvalues)
|
||||
self.verticalLayout_5.setStretch(0, 1)
|
||||
self.verticalLayout_5.setStretch(1, 64)
|
||||
self.verticalLayout_2.addWidget(self.groupBox_14)
|
||||
self.verticalLayout_2.setStretch(0, 1)
|
||||
self.verticalLayout_2.setStretch(1, 32)
|
||||
self.groupBox_19 = QtWidgets.QGroupBox(self.splitter_3)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_19.setFont(font)
|
||||
self.groupBox_19.setObjectName("groupBox_19")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox_19)
|
||||
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout.setSpacing(0)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.horizontalLayout_12 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_12.setSpacing(9)
|
||||
self.horizontalLayout_12.setObjectName("horizontalLayout_12")
|
||||
self.widget_38 = QtWidgets.QWidget(self.groupBox_19)
|
||||
self.widget_38.setObjectName("widget_38")
|
||||
self.horizontalLayout_41 = QtWidgets.QHBoxLayout(self.widget_38)
|
||||
self.horizontalLayout_41.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_41.setSpacing(6)
|
||||
self.horizontalLayout_41.setObjectName("horizontalLayout_41")
|
||||
self.label_target_5 = QtWidgets.QLabel(self.widget_38)
|
||||
self.label_target_5.setObjectName("label_target_5")
|
||||
self.horizontalLayout_41.addWidget(self.label_target_5)
|
||||
self.comboBox_statistics_mode = QtWidgets.QComboBox(self.widget_38)
|
||||
self.comboBox_statistics_mode.setObjectName("comboBox_statistics_mode")
|
||||
self.comboBox_statistics_mode.addItem("")
|
||||
self.comboBox_statistics_mode.addItem("")
|
||||
self.comboBox_statistics_mode.addItem("")
|
||||
self.horizontalLayout_41.addWidget(self.comboBox_statistics_mode)
|
||||
self.label_delay_9 = QtWidgets.QLabel(self.widget_38)
|
||||
self.label_delay_9.setObjectName("label_delay_9")
|
||||
self.horizontalLayout_41.addWidget(self.label_delay_9)
|
||||
self.dateTimeEdit_statistics_time = QtWidgets.QDateTimeEdit(self.widget_38)
|
||||
self.dateTimeEdit_statistics_time.setDateTime(QtCore.QDateTime(QtCore.QDate(2022, 7, 9), QtCore.QTime(0, 0, 0)))
|
||||
self.dateTimeEdit_statistics_time.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2030, 9, 14), QtCore.QTime(0, 0, 0)))
|
||||
self.dateTimeEdit_statistics_time.setMinimumDateTime(QtCore.QDateTime(QtCore.QDate(2022, 7, 1), QtCore.QTime(0, 0, 0)))
|
||||
self.dateTimeEdit_statistics_time.setCurrentSection(QtWidgets.QDateTimeEdit.MinuteSection)
|
||||
self.dateTimeEdit_statistics_time.setCalendarPopup(False)
|
||||
self.dateTimeEdit_statistics_time.setCurrentSectionIndex(4)
|
||||
self.dateTimeEdit_statistics_time.setTimeSpec(QtCore.Qt.LocalTime)
|
||||
self.dateTimeEdit_statistics_time.setObjectName("dateTimeEdit_statistics_time")
|
||||
self.horizontalLayout_41.addWidget(self.dateTimeEdit_statistics_time)
|
||||
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_41.addItem(spacerItem1)
|
||||
self.checkBox_statistics_auto_update = QtWidgets.QCheckBox(self.widget_38)
|
||||
self.checkBox_statistics_auto_update.setChecked(True)
|
||||
self.checkBox_statistics_auto_update.setObjectName("checkBox_statistics_auto_update")
|
||||
self.horizontalLayout_41.addWidget(self.checkBox_statistics_auto_update)
|
||||
self.pushButton_statistics_config = QtWidgets.QPushButton(self.widget_38)
|
||||
self.pushButton_statistics_config.setObjectName("pushButton_statistics_config")
|
||||
self.horizontalLayout_41.addWidget(self.pushButton_statistics_config)
|
||||
self.horizontalLayout_41.setStretch(0, 1)
|
||||
self.horizontalLayout_41.setStretch(1, 4)
|
||||
self.horizontalLayout_41.setStretch(2, 1)
|
||||
self.horizontalLayout_41.setStretch(3, 4)
|
||||
self.horizontalLayout_41.setStretch(4, 6)
|
||||
self.horizontalLayout_41.setStretch(5, 1)
|
||||
self.horizontalLayout_41.setStretch(6, 2)
|
||||
self.horizontalLayout_12.addWidget(self.widget_38)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_12)
|
||||
self.splitter_status_record = QtWidgets.QSplitter(self.groupBox_19)
|
||||
self.splitter_status_record.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.splitter_status_record.setObjectName("splitter_status_record")
|
||||
self.graphicsView_status_record = PlotWidget(self.splitter_status_record)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.graphicsView_status_record.sizePolicy().hasHeightForWidth())
|
||||
self.graphicsView_status_record.setSizePolicy(sizePolicy)
|
||||
self.graphicsView_status_record.setObjectName("graphicsView_status_record")
|
||||
self.tableView_status_record = QtWidgets.QTableView(self.splitter_status_record)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.tableView_status_record.setFont(font)
|
||||
self.tableView_status_record.setAutoScrollMargin(10)
|
||||
self.tableView_status_record.setSortingEnabled(False)
|
||||
self.tableView_status_record.setObjectName("tableView_status_record")
|
||||
self.tableView_status_record.horizontalHeader().setMinimumSectionSize(12)
|
||||
self.tableView_status_record.verticalHeader().setCascadingSectionResizes(True)
|
||||
self.tableView_status_record.verticalHeader().setDefaultSectionSize(20)
|
||||
self.tableView_status_record.verticalHeader().setMinimumSectionSize(5)
|
||||
self.tableView_status_record.verticalHeader().setStretchLastSection(True)
|
||||
self.verticalLayout.addWidget(self.splitter_status_record)
|
||||
self.verticalLayout.setStretch(0, 1)
|
||||
self.verticalLayout.setStretch(1, 64)
|
||||
self.layoutWidget2 = QtWidgets.QWidget(self.splitter_3)
|
||||
self.layoutWidget2.setObjectName("layoutWidget2")
|
||||
self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget2)
|
||||
self.verticalLayout_14.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_14.setSpacing(0)
|
||||
self.verticalLayout_14.setObjectName("verticalLayout_14")
|
||||
self.groupBox_18 = QtWidgets.QGroupBox(self.layoutWidget2)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.groupBox_18.setFont(font)
|
||||
self.groupBox_18.setObjectName("groupBox_18")
|
||||
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox_18)
|
||||
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_3.setSpacing(0)
|
||||
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||
self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_9.setSpacing(9)
|
||||
self.horizontalLayout_9.setObjectName("horizontalLayout_9")
|
||||
self.label_target_4 = QtWidgets.QLabel(self.groupBox_18)
|
||||
self.label_target_4.setObjectName("label_target_4")
|
||||
self.horizontalLayout_9.addWidget(self.label_target_4)
|
||||
self.comboBox_collect_target = QtWidgets.QComboBox(self.groupBox_18)
|
||||
self.comboBox_collect_target.setObjectName("comboBox_collect_target")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.comboBox_collect_target.addItem("")
|
||||
self.horizontalLayout_9.addWidget(self.comboBox_collect_target)
|
||||
self.label_delay = QtWidgets.QLabel(self.groupBox_18)
|
||||
self.label_delay.setObjectName("label_delay")
|
||||
self.horizontalLayout_9.addWidget(self.label_delay)
|
||||
self.timeEdit_collect_delay = QtWidgets.QTimeEdit(self.groupBox_18)
|
||||
self.timeEdit_collect_delay.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2000, 1, 1), QtCore.QTime(23, 59, 59)))
|
||||
self.timeEdit_collect_delay.setCurrentSection(QtWidgets.QDateTimeEdit.MinuteSection)
|
||||
self.timeEdit_collect_delay.setCurrentSectionIndex(1)
|
||||
self.timeEdit_collect_delay.setTime(QtCore.QTime(0, 0, 0))
|
||||
self.timeEdit_collect_delay.setObjectName("timeEdit_collect_delay")
|
||||
self.horizontalLayout_9.addWidget(self.timeEdit_collect_delay)
|
||||
self.label_duration = QtWidgets.QLabel(self.groupBox_18)
|
||||
self.label_duration.setObjectName("label_duration")
|
||||
self.horizontalLayout_9.addWidget(self.label_duration)
|
||||
self.spinBox_collect_duration = QtWidgets.QSpinBox(self.groupBox_18)
|
||||
self.spinBox_collect_duration.setMinimum(50)
|
||||
self.spinBox_collect_duration.setMaximum(100000000)
|
||||
self.spinBox_collect_duration.setSingleStep(10)
|
||||
self.spinBox_collect_duration.setProperty("value", 500)
|
||||
self.spinBox_collect_duration.setDisplayIntegerBase(10)
|
||||
self.spinBox_collect_duration.setObjectName("spinBox_collect_duration")
|
||||
self.horizontalLayout_9.addWidget(self.spinBox_collect_duration)
|
||||
self.label_number = QtWidgets.QLabel(self.groupBox_18)
|
||||
self.label_number.setObjectName("label_number")
|
||||
self.horizontalLayout_9.addWidget(self.label_number)
|
||||
self.spinBox_collect_number = QtWidgets.QSpinBox(self.groupBox_18)
|
||||
self.spinBox_collect_number.setMinimum(0)
|
||||
self.spinBox_collect_number.setMaximum(10000)
|
||||
self.spinBox_collect_number.setProperty("value", 1)
|
||||
self.spinBox_collect_number.setObjectName("spinBox_collect_number")
|
||||
self.horizontalLayout_9.addWidget(self.spinBox_collect_number)
|
||||
self.pushButton_collect_clean = QtWidgets.QPushButton(self.groupBox_18)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.pushButton_collect_clean.setFont(font)
|
||||
self.pushButton_collect_clean.setObjectName("pushButton_collect_clean")
|
||||
self.horizontalLayout_9.addWidget(self.pushButton_collect_clean)
|
||||
self.pushButton_collect_start = QtWidgets.QPushButton(self.groupBox_18)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
|
||||
self.pushButton_collect_start.setFont(font)
|
||||
self.pushButton_collect_start.setAutoDefault(False)
|
||||
self.pushButton_collect_start.setDefault(False)
|
||||
self.pushButton_collect_start.setObjectName("pushButton_collect_start")
|
||||
self.horizontalLayout_9.addWidget(self.pushButton_collect_start)
|
||||
self.horizontalLayout_9.setStretch(0, 1)
|
||||
self.horizontalLayout_9.setStretch(1, 3)
|
||||
self.horizontalLayout_9.setStretch(2, 1)
|
||||
self.horizontalLayout_9.setStretch(3, 3)
|
||||
self.horizontalLayout_9.setStretch(4, 1)
|
||||
self.horizontalLayout_9.setStretch(5, 3)
|
||||
self.horizontalLayout_9.setStretch(6, 1)
|
||||
self.horizontalLayout_9.setStretch(7, 3)
|
||||
self.horizontalLayout_9.setStretch(8, 1)
|
||||
self.horizontalLayout_9.setStretch(9, 3)
|
||||
self.verticalLayout_3.addLayout(self.horizontalLayout_9)
|
||||
self.verticalLayout_14.addWidget(self.groupBox_18)
|
||||
self.verticalLayout_14.setStretch(0, 1)
|
||||
self.verticalLayout_14.setStretch(1, 32)
|
||||
self.verticalLayout_18.addWidget(self.splitter_3)
|
||||
self.verticalLayout_17.addWidget(self.splitter_display)
|
||||
self.verticalLayout_17.setStretch(0, 1)
|
||||
self.verticalLayout_17.setStretch(1, 128)
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||
MainWindow.setTabOrder(self.graphicsView_subcarrier, self.graphicsView_rssi)
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MainWindow.setWindowTitle(_translate("MainWindow", "ESP_CSI_TOOL"))
|
||||
self.label_2.setText(_translate("MainWindow", "display:"))
|
||||
self.checkBox_raw_data.setText(_translate("MainWindow", "Raw data"))
|
||||
self.checkBox_radar_model.setText(_translate("MainWindow", "Radar model"))
|
||||
self.groupBox_raw_data.setTitle(_translate("MainWindow", "Raw data"))
|
||||
self.groupBox_16.setTitle(_translate("MainWindow", "Command"))
|
||||
self.groupBox_11.setTitle(_translate("MainWindow", "router"))
|
||||
self.label_delay_2.setText(_translate("MainWindow", "ssid "))
|
||||
self.label_duration_2.setText(_translate("MainWindow", "password"))
|
||||
self.checkBox_router_auto_connect.setText(_translate("MainWindow", "atuto connect"))
|
||||
self.pushButton_router_connect.setText(_translate("MainWindow", "connect"))
|
||||
self.label.setText(_translate("MainWindow", "custom"))
|
||||
self.comboBox_command.setItemText(0, _translate("MainWindow", "NULL"))
|
||||
self.comboBox_command.setItemText(1, _translate("MainWindow", "restart"))
|
||||
self.comboBox_command.setItemText(2, _translate("MainWindow", "radar --output LLFT"))
|
||||
self.comboBox_command.setItemText(3, _translate("MainWindow", "version"))
|
||||
self.comboBox_command.setItemText(4, _translate("MainWindow", "wifi_config --info"))
|
||||
self.comboBox_command.setItemText(5, _translate("MainWindow", "wifi_scan"))
|
||||
self.comboBox_command.setItemText(6, _translate("MainWindow", "ping --abort"))
|
||||
self.pushButton_command.setText(_translate("MainWindow", "send"))
|
||||
self.groupBox_subcarrier.setTitle(_translate("MainWindow", "subcarrier amplitude"))
|
||||
self.checkBox_wave_filtering.setText(_translate("MainWindow", "wave filtering"))
|
||||
self.groupBox_rssi.setTitle(_translate("MainWindow", "RSSI"))
|
||||
self.groupBox_13.setTitle(_translate("MainWindow", "log"))
|
||||
self.groupBox_radioHeader.setTitle(_translate("MainWindow", "info"))
|
||||
self.groupBox_radar_model.setTitle(_translate("MainWindow", "Radar model"))
|
||||
self.groupBox_15.setTitle(_translate("MainWindow", "Train"))
|
||||
self.label_delay_5.setText(_translate("MainWindow", "delay"))
|
||||
self.timeEdit_train_delay.setDisplayFormat(_translate("MainWindow", "HH:mm:ss"))
|
||||
self.label_delay_6.setText(_translate("MainWindow", "duration"))
|
||||
self.timeEdit_train_duration.setDisplayFormat(_translate("MainWindow", "HH:mm:ss"))
|
||||
self.checkBox_train_add.setText(_translate("MainWindow", "Add"))
|
||||
self.pushButton_train_start.setText(_translate("MainWindow", "start"))
|
||||
self.groupBox_14.setTitle(_translate("MainWindow", "Predict"))
|
||||
self.label_number_3.setText(_translate("MainWindow", "someone sensitivity"))
|
||||
self.label_number_5.setText(_translate("MainWindow", "move sensitivity"))
|
||||
self.label_duration_7.setText(_translate("MainWindow", "filter outliers"))
|
||||
self.checkBox_display_eigenvalues_table.setText(_translate("MainWindow", "display table"))
|
||||
self.pushButton_predict_config.setText(_translate("MainWindow", "config"))
|
||||
self.groupBox_19.setTitle(_translate("MainWindow", "Statistics"))
|
||||
self.label_target_5.setText(_translate("MainWindow", "mode"))
|
||||
self.comboBox_statistics_mode.setItemText(0, _translate("MainWindow", "minute"))
|
||||
self.comboBox_statistics_mode.setItemText(1, _translate("MainWindow", "hour"))
|
||||
self.comboBox_statistics_mode.setItemText(2, _translate("MainWindow", "day"))
|
||||
self.label_delay_9.setText(_translate("MainWindow", "time"))
|
||||
self.dateTimeEdit_statistics_time.setDisplayFormat(_translate("MainWindow", "yyyy-MM-dd HH:mm:ss"))
|
||||
self.checkBox_statistics_auto_update.setText(_translate("MainWindow", "auto update"))
|
||||
self.pushButton_statistics_config.setText(_translate("MainWindow", "update"))
|
||||
self.groupBox_18.setTitle(_translate("MainWindow", "Collect"))
|
||||
self.label_target_4.setText(_translate("MainWindow", "target"))
|
||||
self.comboBox_collect_target.setItemText(0, _translate("MainWindow", "unknown"))
|
||||
self.comboBox_collect_target.setItemText(1, _translate("MainWindow", "train"))
|
||||
self.comboBox_collect_target.setItemText(2, _translate("MainWindow", "none"))
|
||||
self.comboBox_collect_target.setItemText(3, _translate("MainWindow", "someone"))
|
||||
self.comboBox_collect_target.setItemText(4, _translate("MainWindow", "static"))
|
||||
self.comboBox_collect_target.setItemText(5, _translate("MainWindow", "move"))
|
||||
self.comboBox_collect_target.setItemText(6, _translate("MainWindow", "front"))
|
||||
self.comboBox_collect_target.setItemText(7, _translate("MainWindow", "after"))
|
||||
self.comboBox_collect_target.setItemText(8, _translate("MainWindow", "left"))
|
||||
self.comboBox_collect_target.setItemText(9, _translate("MainWindow", "right"))
|
||||
self.comboBox_collect_target.setItemText(10, _translate("MainWindow", "go"))
|
||||
self.comboBox_collect_target.setItemText(11, _translate("MainWindow", "jump"))
|
||||
self.comboBox_collect_target.setItemText(12, _translate("MainWindow", "sit down"))
|
||||
self.comboBox_collect_target.setItemText(13, _translate("MainWindow", "stand up"))
|
||||
self.comboBox_collect_target.setItemText(14, _translate("MainWindow", "climb up"))
|
||||
self.comboBox_collect_target.setItemText(15, _translate("MainWindow", "wave"))
|
||||
self.comboBox_collect_target.setItemText(16, _translate("MainWindow", "applause"))
|
||||
self.label_delay.setText(_translate("MainWindow", "delay"))
|
||||
self.timeEdit_collect_delay.setDisplayFormat(_translate("MainWindow", "HH:mm:ss"))
|
||||
self.label_duration.setText(_translate("MainWindow", "duration(ms)"))
|
||||
self.label_number.setText(_translate("MainWindow", "number"))
|
||||
self.pushButton_collect_clean.setText(_translate("MainWindow", "clean"))
|
||||
self.pushButton_collect_start.setText(_translate("MainWindow", "start"))
|
||||
from pyqtgraph import PlotWidget
|
||||
1665
esp-radar/console_test/tools/esp_csi_tool_gui.ui
Normal file
1665
esp-radar/console_test/tools/esp_csi_tool_gui.ui
Normal file
File diff suppressed because it is too large
Load Diff
8
esp-radar/console_test/tools/requirements.txt
Normal file
8
esp-radar/console_test/tools/requirements.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
argparse
|
||||
pandas
|
||||
numpy
|
||||
path
|
||||
PyQt5
|
||||
pyqtgraph
|
||||
pyserial
|
||||
scipy
|
||||
Reference in New Issue
Block a user