blob: 794adda18765b9e566698c27e458b385e36e888a [file] [log] [blame]
shuai.liua6249432024-09-10 09:30:42 +00001// Copyright (C) 2024 Amlogic, Inc. All rights reserved.
2//
3// All information contained herein is Amlogic confidential.
4//
5// This software is provided to you pursuant to Software License
6// Agreement (SLA) with Amlogic Inc ("Amlogic"). This software may be
7// used only in accordance with the terms of this agreement.
8//
9// Redistribution and use in source and binary forms, with or without
10// modification is strictly prohibited without prior written permission
11// from Amlogic.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25#include <unistd.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <sys/time.h>
29#include <string.h>
30#include <semaphore.h>
31#include <time.h>
32
33#include <thread>
34#include <string>
35#include <iostream>
36#include <chrono>
37
38#include "alg_lib/include/iva/iva_wisense_ppd.hpp"
39
40extern "C" {
41#include "csi_lib/aml_csi.h"
42}
43
44static int cnt = 0;
45static int motion_status = -1;
46static WiSenseIn g_csi_buffer;
47static WiSenseIn *g_csi_detail = &g_csi_buffer;
48
49static aai_iva_wisense_ppd_handle_t iva_wisense_ppd_handle;
50static aai_iva_wisense_ppd_output_t wi_out_ret;
51static aai_iva_wisense_ppd_input_t wi_in;
52static aai_iva_wisense_ppd_mlevel_t mlevel;
53static aai_iva_wisense_ppd_param_t params;
54static std::string g_ctimes = "";
55
56static volatile bool keep_running = true;
57static sem_t semaphore;
58
59/*print different colors*/
60#define RED "\033[31m" /* Red */
61#define GREEN "\033[32m" /* Green */
62#define YELLOW "\033[33m" /* Yellow */
63#define BLUE "\033[34m" /* Blue */
64#define MAGENTA "\033[35m" /* Magenta */
65#define CYAN "\033[36m" /* Cyan */
66#define WHITE "\033[37m" /* White */
67
68/*
69copy csi to WiSenseIn struct,when get csi about 20 packets, send them to algorithm api
70*/
71void csi_cb(unsigned char *csi_data, int csi_data_lean) {
72 csi_stream *c = (csi_stream *)csi_data;
73
74 if (keep_running) {
75 if (cnt < 20) {
76 g_csi_detail->time_stamp[cnt] = c->time_stamp;
77 g_csi_detail->rssi[cnt][0] = c->rssi[0];
78 g_csi_detail->rssi[cnt][1] = c->rssi[1];
79 g_csi_detail->bw[cnt] = static_cast<int>((unsigned char)c->bw);
80 g_csi_detail->ntx[cnt] = c->ntx;
81 g_csi_detail->channel[cnt] = c->channel;
82 g_csi_detail->protocol_mode[cnt] = c->protocol_mode;
83 memcpy(g_csi_detail->csi[cnt], c->csi, 4 * 1024);
84
85 cnt++;
86 if (cnt == 20) {
87 sem_post(&semaphore);
88 }
89 }
90 }
91}
92
93void csi_data_collection_start(void)
94{
95 int interval = 50;
96 int period = 0;
97
98 csi_enable_debug(0);
99 ping_start(NULL, 50);
100 csi_register_data_recv_func(NULL, csi_cb);
101 csi_set_config(NULL, interval, 1);
102 csi_set_filter(0, 0, 0, 0, NULL, NULL,0, NULL);
103 csi_start(&period);
104
105 return;
106}
107
108void csi_data_collection_end(void)
109{
110 csi_stop(NULL);
111 ping_stop();
112}
113
114/*
115 * @brief If you want to turn on the light when motion is wisense detected,
116 * you can define WISENSE_LED_ACTION macro and specify the gpio num on your board.
117 * */
118void wisense_led_init(void)
119{
120#if WISENSE_LED_ACTION
121 system("echo 449 > /sys/class/gpio/export");
122 system("echo out > /sys/class/gpio/gpio449/direction");
123#endif
124}
125
126/*
127 * @brief If you want to turn on the light when wisense motion is detected,
128 * you can define WISENSE_LED_ACTION macro and specify the gpio num on your board.
129 * */
130void wisense_led_set(int value)
131{
132#if WISENSE_DEBUG
133 std::chrono::milliseconds ms = std::chrono::duration_cast< std::chrono::milliseconds >(
134 std::chrono::system_clock::now().time_since_epoch()
135 );
136 std::cout << ms.count()/100 << std::endl;
137#endif
138
139 std::cout << "--->motion status is " << value << std::endl;
140#if WISENSE_LED_ACTION
141 if (value) {
142 system("echo 1 > /sys/class/gpio/gpio449/value"); // Red led
143 else
144 system("echo 0 > /sys/class/gpio/gpio449/value"); // Green led
145#endif
146}
147
148void update_current_time(void) {
149 auto now = std::chrono::system_clock::now();
150 auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
151 std::time_t t = std::chrono::system_clock::to_time_t(now_ms);
152 std::tm *now_tm = std::localtime(&t);
153 char buffer[100];
154 std::strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", now_tm);
155 g_ctimes = buffer;
156}
157
158void* wisense_processing_thread(void* arg)
159{
160 while (keep_running) {
161 sem_wait(&semaphore);
162 if (cnt >= 20) {
163 cnt = 0;
164 update_current_time();
165 wi_in.wisenseIn = g_csi_detail;
166 aai_iva_wisense_ppd_detect(iva_wisense_ppd_handle, wi_in, wi_out_ret, params);
167 motion_status = wi_out_ret.motion_status;
168 wisense_led_set(motion_status);
169 switch (wi_out_ret.motion_class) {
170 case 1:
171 std::cout << RED << "Motion class is 1. Large human activity in close range[TX/RX] at " << g_ctimes << "\033[0m\n";
172 break;
173 case 2:
174 std::cout << MAGENTA << "Motion class is 2. Human activity at " << g_ctimes << "\033[0m\n";
175 break;
176 case 3:
177 std::cout << GREEN << "Motion class is 3. Human activity at " << g_ctimes << "\033[0m\n";
178 break;
179 case 4:
180 std::cout << GREEN << "Motion class is 4. Lightweight motion. Human activity at " << g_ctimes << "\033[0m\n";
181 break;
182 case 5:
183 std::cout << GREEN << "Motion class is 5. Lightweight motion. Human activity at " << g_ctimes << "\033[0m\n";
184 break;
185 default:
186 std::cout << YELLOW << "Motion class is 0, No person activity detect at " << g_ctimes << "\033[0m\n";
187 break;
188 }
189 }
190 }
191
192 return NULL;
193}
194
195int main(int argc, char** argv)
196{
197 int opt;
198 int mlevel = 4;
199
200 while ((opt = getopt(argc, argv, "l:")) != -1) {
201 switch (opt)
202 {
203 case 'l':
204 mlevel = atoi(optarg);
205 break;
206 default:
207 break;
208 }
209 }
210
211
212 sem_init(&semaphore, 0, 0);
213
214 wisense_led_init();
215 csi_data_collection_start();
216
217 iva_wisense_ppd_handle = aai_iva_wisense_ppd_init(params);
218
219 if (iva_wisense_ppd_handle != NULL) {
220 params.e_mlevel = static_cast<aai_iva_wisense_ppd_mlevel_t>(mlevel);
221 aai_iva_wisense_ppd_param_set(iva_wisense_ppd_handle, params);
222 std::thread wisense_thread(wisense_processing_thread, nullptr);
223 wisense_thread.join();
224 }
225
226 csi_data_collection_end();
227
228 if (iva_wisense_ppd_handle != NULL) {
229 aai_iva_wisense_ppd_deinit(iva_wisense_ppd_handle);
230 }
231
232 sem_destroy(&semaphore);
233
234 return 0;
235}
236