237 lines
6.6 KiB
C++
237 lines
6.6 KiB
C++
// 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 <unistd.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <sys/time.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <semaphore.h>
|
||
|
|
#include <time.h>
|
||
|
|
|
||
|
|
#include <thread>
|
||
|
|
#include <string>
|
||
|
|
#include <iostream>
|
||
|
|
#include <chrono>
|
||
|
|
|
||
|
|
#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<int>((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<std::chrono::milliseconds>(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<aai_iva_wisense_ppd_mlevel_t>(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;
|
||
|
|
}
|
||
|
|
|