// Copyright (C) 2024 Amlogic, Inc. All rights reserved. // // All information contained herein is Amlogic confidential. // // This software is provided to you pursuant to Software License // Agreement (SLA) with Amlogic Inc ("Amlogic"). This software may be // used only in accordance with the terms of this agreement. // // Redistribution and use in source and binary forms, with or without // modification is strictly prohibited without prior written permission // from Amlogic. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include #include #include #include #include #include #include #include #include #include "alg_lib/include/iva/iva_wisense_ppd.hpp" extern "C" { #include "csi_lib/aml_csi.h" } static int cnt = 0; static int motion_status = -1; static WiSenseIn g_csi_buffer; static WiSenseIn *g_csi_detail = &g_csi_buffer; static aai_iva_wisense_ppd_handle_t iva_wisense_ppd_handle; static aai_iva_wisense_ppd_output_t wi_out_ret; static aai_iva_wisense_ppd_input_t wi_in; static aai_iva_wisense_ppd_mlevel_t mlevel; static aai_iva_wisense_ppd_param_t params; static std::string g_ctimes = ""; static volatile bool keep_running = true; static sem_t semaphore; /*print different colors*/ #define RED "\033[31m" /* Red */ #define GREEN "\033[32m" /* Green */ #define YELLOW "\033[33m" /* Yellow */ #define BLUE "\033[34m" /* Blue */ #define MAGENTA "\033[35m" /* Magenta */ #define CYAN "\033[36m" /* Cyan */ #define WHITE "\033[37m" /* White */ /* copy csi to WiSenseIn struct,when get csi about 20 packets, send them to algorithm api */ void csi_cb(unsigned char *csi_data, int csi_data_lean) { csi_stream *c = (csi_stream *)csi_data; if (keep_running) { if (cnt < 20) { g_csi_detail->time_stamp[cnt] = c->time_stamp; g_csi_detail->rssi[cnt][0] = c->rssi[0]; g_csi_detail->rssi[cnt][1] = c->rssi[1]; g_csi_detail->bw[cnt] = static_cast((unsigned char)c->bw); g_csi_detail->ntx[cnt] = c->ntx; g_csi_detail->channel[cnt] = c->channel; g_csi_detail->protocol_mode[cnt] = c->protocol_mode; memcpy(g_csi_detail->csi[cnt], c->csi, 4 * 1024); cnt++; if (cnt == 20) { sem_post(&semaphore); } } } } void csi_data_collection_start(void) { int interval = 50; int period = 0; csi_enable_debug(0); ping_start(NULL, 50); csi_register_data_recv_func(NULL, csi_cb); csi_set_config(NULL, interval, 1); csi_set_filter(0, 0, 0, 0, NULL, NULL,0, NULL); csi_start(&period); return; } void csi_data_collection_end(void) { csi_stop(NULL); ping_stop(); } /* * @brief If you want to turn on the light when motion is wisense detected, * you can define WISENSE_LED_ACTION macro and specify the gpio num on your board. * */ void wisense_led_init(void) { #if WISENSE_LED_ACTION system("echo 449 > /sys/class/gpio/export"); system("echo out > /sys/class/gpio/gpio449/direction"); #endif } /* * @brief If you want to turn on the light when wisense motion is detected, * you can define WISENSE_LED_ACTION macro and specify the gpio num on your board. * */ void wisense_led_set(int value) { #if WISENSE_DEBUG std::chrono::milliseconds ms = std::chrono::duration_cast< std::chrono::milliseconds >( std::chrono::system_clock::now().time_since_epoch() ); std::cout << ms.count()/100 << std::endl; #endif std::cout << "--->motion status is " << value << std::endl; #if WISENSE_LED_ACTION if (value) { system("echo 1 > /sys/class/gpio/gpio449/value"); // Red led else system("echo 0 > /sys/class/gpio/gpio449/value"); // Green led #endif } void update_current_time(void) { auto now = std::chrono::system_clock::now(); auto now_ms = std::chrono::time_point_cast(now); std::time_t t = std::chrono::system_clock::to_time_t(now_ms); std::tm *now_tm = std::localtime(&t); char buffer[100]; std::strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", now_tm); g_ctimes = buffer; } void* wisense_processing_thread(void* arg) { while (keep_running) { sem_wait(&semaphore); if (cnt >= 20) { cnt = 0; update_current_time(); wi_in.wisenseIn = g_csi_detail; aai_iva_wisense_ppd_detect(iva_wisense_ppd_handle, wi_in, wi_out_ret, params); motion_status = wi_out_ret.motion_status; wisense_led_set(motion_status); switch (wi_out_ret.motion_class) { case 1: std::cout << RED << "Motion class is 1. Large human activity in close range[TX/RX] at " << g_ctimes << "\033[0m\n"; break; case 2: std::cout << MAGENTA << "Motion class is 2. Human activity at " << g_ctimes << "\033[0m\n"; break; case 3: std::cout << GREEN << "Motion class is 3. Human activity at " << g_ctimes << "\033[0m\n"; break; case 4: std::cout << GREEN << "Motion class is 4. Lightweight motion. Human activity at " << g_ctimes << "\033[0m\n"; break; case 5: std::cout << GREEN << "Motion class is 5. Lightweight motion. Human activity at " << g_ctimes << "\033[0m\n"; break; default: std::cout << YELLOW << "Motion class is 0, No person activity detect at " << g_ctimes << "\033[0m\n"; break; } } } return NULL; } int main(int argc, char** argv) { int opt; int mlevel = 4; while ((opt = getopt(argc, argv, "l:")) != -1) { switch (opt) { case 'l': mlevel = atoi(optarg); break; default: break; } } sem_init(&semaphore, 0, 0); wisense_led_init(); csi_data_collection_start(); iva_wisense_ppd_handle = aai_iva_wisense_ppd_init(params); if (iva_wisense_ppd_handle != NULL) { params.e_mlevel = static_cast(mlevel); aai_iva_wisense_ppd_param_set(iva_wisense_ppd_handle, params); std::thread wisense_thread(wisense_processing_thread, nullptr); wisense_thread.join(); } csi_data_collection_end(); if (iva_wisense_ppd_handle != NULL) { aai_iva_wisense_ppd_deinit(iva_wisense_ppd_handle); } sem_destroy(&semaphore); return 0; }