Files
Payload_SDK_V2.2.1_300tc/sample/api_sample/widget/test_widget.c
tangchao0503 109e0a8f2b 1、操作遥控器按钮,psdk进程通过socket发送命令给相机进程 来控制高光谱采集系统;
2、通过FFmpeg采集摄像头视频流并编码为h264,利用psdk推流到遥控器;
2022-06-22 16:48:50 +08:00

635 lines
21 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
********************************************************************
* @file test_widget.c
* @version V2.0.0
* @date 2019/07/01
* @brief
*
* @copyright (c) 2018-2019 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJIs authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "test_widget.h"
#include <psdk_widget.h>
#include <psdk_logger.h>
#include <utils/util_misc.h>
#include <psdk_platform.h>
#include <stdio.h>
//sbg
#include <stdlib.h>
#include <string.h>
#if !PSDK_ARCH_SYS_LINUX
#include "file_binary_array_list_en.h"
#endif
/* Private constants ---------------------------------------------------------*/
#define WIDGET_DIR_PATH_LEN_MAX (256)
#define WIDGET_TASK_STACK_SIZE (2048)
/* Private types -------------------------------------------------------------*/
/* Private functions declaration ---------------------------------------------*/
static void *PsdkTest_WidgetTask(void *arg);
static T_PsdkReturnCode PsdkTestWidget_SetWidgetValue(E_PsdkWidgetType widgetType, uint32_t index, int32_t value,
void *userData);
static T_PsdkReturnCode PsdkTestWidget_GetWidgetValue(E_PsdkWidgetType widgetType, uint32_t index, int32_t *value,
void *userData);
static T_PsdkReturnCode PsdkTestWidget_SetWidgetValue_StartRecord(E_PsdkWidgetType widgetType, uint32_t index, int32_t value,
void *userData);
static void *PsdkTest_IrisRecordSystemChanged(void *arg);
/* Private values ------------------------------------------------------------*/
static T_PsdkTaskHandle s_widgetTestThread;
static T_PsdkTaskHandle s_widgetSbgThread;
static T_PsdkTaskHandle s_widgetXimeaThread;
int SbgRecordCondition=0;
static int s_sbgMagState=0;
static int s_stateOfXimea=0;
static int s_stateOfSbg=0;
static int s_stateOfFile=0;
static char * s_strStateOfSbg="未打开";
static char * s_strSbgMagState="等待磁矫正";
static char * s_strSbgAccuracy="1000";
static char * s_strSbgSolutionMode="UNINITIALIZED";
static char * s_strStateOfXimea="未打开";
static char * s_strStateOfFile="等待拷贝数据";
static int s_sockfd;
static struct sockaddr_in s_server;
#if PSDK_ARCH_SYS_LINUX
static bool s_isWidgetFileDirPathConfigured = false;
static char s_widgetFileDirPath[PSDK_FILE_PATH_SIZE_MAX] = {0};
#endif
static const T_PsdkWidgetHandlerListItem s_widgetHandlerList[] = {
{0, PSDK_WIDGET_TYPE_BUTTON, PsdkTestWidget_SetWidgetValue, PsdkTestWidget_GetWidgetValue, NULL},
{1, PSDK_WIDGET_TYPE_BUTTON, PsdkTestWidget_SetWidgetValue, PsdkTestWidget_GetWidgetValue, NULL},
{2, PSDK_WIDGET_TYPE_LIST, PsdkTestWidget_SetWidgetValue_StartRecord, PsdkTestWidget_GetWidgetValue, NULL},
{3, PSDK_WIDGET_TYPE_SWITCH, PsdkTestWidget_SetWidgetValue_StartRecord, PsdkTestWidget_GetWidgetValue, NULL},
{4, PSDK_WIDGET_TYPE_SCALE, PsdkTestWidget_SetWidgetValue, PsdkTestWidget_GetWidgetValue, NULL},
{5, PSDK_WIDGET_TYPE_BUTTON, PsdkTestWidget_SetWidgetValue_StartRecord, PsdkTestWidget_GetWidgetValue, NULL},
{6, PSDK_WIDGET_TYPE_SCALE, PsdkTestWidget_SetWidgetValue_StartRecord, PsdkTestWidget_GetWidgetValue, NULL},
{7, PSDK_WIDGET_TYPE_INT_INPUT_BOX, PsdkTestWidget_SetWidgetValue, PsdkTestWidget_GetWidgetValue, NULL},
{8, PSDK_WIDGET_TYPE_SWITCH, PsdkTestWidget_SetWidgetValue_StartRecord, PsdkTestWidget_GetWidgetValue, NULL},
{9, PSDK_WIDGET_TYPE_LIST, PsdkTestWidget_SetWidgetValue_StartRecord, PsdkTestWidget_GetWidgetValue, NULL},//PsdkTestWidget_SetWidgetValue
};
static char *s_widgetTypeNameArray[] = {
"Unknown",
"Button",
"Switch",
"Scale",
"List",
"Int input box"
};
static const uint32_t s_widgetHandlerListCount = sizeof(s_widgetHandlerList) / sizeof(T_PsdkWidgetHandlerListItem);
static int32_t s_widgetValueList[sizeof(s_widgetHandlerList) / sizeof(T_PsdkWidgetHandlerListItem)] = {0};
/* Exported functions definition ---------------------------------------------*/
T_PsdkReturnCode PsdkTest_WidgetInit(void)
{
T_PsdkReturnCode psdkStat;
//Step 1 : Init PSDK Widget
psdkStat = PsdkWidget_Init();
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Psdk test widget init error, stat = 0x%08llX", psdkStat);
return psdkStat;
}
#if PSDK_ARCH_SYS_LINUX
//Step 2 : Set UI Config (Linux environment)
//获取控件图像和UI配置文件所在文件夹
PsdkLogger_UserLogInfo("验证是否定义了宏PSDK_ARCH_SYS_LINUX:是!--------------------------------------------------------------------------------------------------------------------------");
char curFileDirPath[WIDGET_DIR_PATH_LEN_MAX];
char tempPath[WIDGET_DIR_PATH_LEN_MAX];
psdkStat = PsdkUserUtil_GetCurrentFileDirPath(__FILE__, WIDGET_DIR_PATH_LEN_MAX, curFileDirPath);
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Get file current path error, stat = 0x%08llX", psdkStat);
return psdkStat;
}
if (s_isWidgetFileDirPathConfigured == true) {
snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/en_big_screen", s_widgetFileDirPath);
} else {
snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/en_big_screen", curFileDirPath);
}
//set default ui config path
psdkStat = PsdkWidget_RegDefaultUiConfigByDirPath(tempPath);
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Add default widget ui config error, stat = 0x%08llX", psdkStat);
return psdkStat;
}
//set ui config for English language
//设置系统语言为英文时控件配置文件的路径
psdkStat = PsdkWidget_RegUiConfigByDirPath(PSDK_AIRCRAFT_INFO_MOBILE_APP_LANGUAGE_ENGLISH,
PSDK_AIRCRAFT_INFO_MOBILE_APP_SCREEN_TYPE_BIG_SCREEN,
tempPath);
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Add widget ui config error, stat = 0x%08llX", psdkStat);
return psdkStat;
}
//set ui config for Chinese language
if (s_isWidgetFileDirPathConfigured == true) {
snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/cn_big_screen", s_widgetFileDirPath);
} else {
snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/cn_big_screen", curFileDirPath);
}
psdkStat = PsdkWidget_RegUiConfigByDirPath(PSDK_AIRCRAFT_INFO_MOBILE_APP_LANGUAGE_CHINESE,
PSDK_AIRCRAFT_INFO_MOBILE_APP_SCREEN_TYPE_BIG_SCREEN,
tempPath);
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Add widget ui config error, stat = 0x%08llX", psdkStat);
return psdkStat;
}
#else
//Step 2 : Set UI Config (RTOS environment)
T_PsdkWidgetBinaryArrayConfig enWidgetBinaryArrayConfig = {
.binaryArrayCount = g_EnBinaryArrayCount,
.fileBinaryArrayList = g_EnFileBinaryArrayList
};
//set default ui config
psdkStat = PsdkWidget_RegDefaultUiConfigByBinaryArray(&enWidgetBinaryArrayConfig);
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Add default widget ui config error, stat = 0x%08llX", psdkStat);
return psdkStat;
}
#endif
//Step 3 : Set widget handler list
psdkStat = PsdkWidget_RegHandlerList(s_widgetHandlerList, s_widgetHandlerListCount);
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Set widget handler list error, stat = 0x%08llX", psdkStat);
return psdkStat;
}
//Step 4 : Run widget api sample task
if (PsdkOsal_TaskCreate(&s_widgetTestThread, PsdkTest_WidgetTask, "user_widget_task", WIDGET_TASK_STACK_SIZE,
NULL) != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Psdk widget test task create error.");
return PSDK_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
//Step 5 : Run ximea task
if (PsdkOsal_TaskCreate(&s_widgetXimeaThread, PsdkTest_IrisRecordSystemChanged, "ximea", WIDGET_TASK_STACK_SIZE,
NULL) != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Psdk widget test task(ximea) create error.");
return PSDK_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
/* tc-----------------------------------------------*/
struct hostent *he;
he=gethostbyname("127.0.0.1");
s_sockfd=socket(AF_INET, SOCK_DGRAM,0);
bzero(&s_server,sizeof(s_server));
s_server.sin_family = AF_INET;
s_server.sin_port = htons(PORT);
s_server.sin_addr= *((struct in_addr *)he->h_addr);
/* tc-----------------------------------------------*/
return PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
#if PSDK_ARCH_SYS_LINUX
T_PsdkReturnCode PsdkTest_WidgetSetConfigFilePath(const char *path)
{
memset(s_widgetFileDirPath, 0, sizeof(s_widgetFileDirPath));
memcpy(s_widgetFileDirPath, path, USER_UTIL_MIN(strlen(path), sizeof(s_widgetFileDirPath) - 1));
s_isWidgetFileDirPathConfigured = true;
return PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
#endif
#ifndef __CC_ARM
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#pragma GCC diagnostic ignored "-Wreturn-type"
#pragma GCC diagnostic ignored "-Wformat"
#endif
/* Private functions definition-----------------------------------------------*/
//在DJI pilot的浮窗上显示系统时间
static void *PsdkTest_WidgetTask(void *arg)
{
char message[PSDK_WIDGET_FLOATING_WINDOW_MSG_MAX_LEN];
uint32_t sysTimeMs = 0;
T_PsdkReturnCode psdkStat;
USER_UTIL_UNUSED(arg);
while (1) {
psdkStat = PsdkOsal_GetTimeMs(&sysTimeMs);
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Get system time ms error, stat = 0x%08llX", psdkStat);
}
//snprintf(message, PSDK_WIDGET_FLOATING_WINDOW_MSG_MAX_LEN, "System time: %u ms;\nMAG: %d;\nIMAGER: %d;\nIMU: %d;\nFile: %d;\n", sysTimeMs, s_sbgMagState, s_stateOfXimea, s_stateOfSbg, s_stateOfFile);
snprintf(message, PSDK_WIDGET_FLOATING_WINDOW_MSG_MAX_LEN, "System time: %u ms;\n磁场矫正: %s;\n光谱仪: %s;\n惯导: %s;\n精度: %s;\nmode: %s;\n文件: %s;\n", sysTimeMs, s_strSbgMagState, s_strStateOfXimea, s_strStateOfSbg, s_strSbgAccuracy, s_strSbgSolutionMode, s_strStateOfFile);
psdkStat = PsdkWidgetFloatingWindow_ShowMessage(message);
if (psdkStat != PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Floating window show message error, stat = 0x%08llX", psdkStat);
}
PsdkOsal_TaskSleepMs(1000);
}
}
static void *PsdkTest_IrisRecordSystemChanged(void *arg)//
{
// FILE * fp;
// char buffer[80];
// fp = popen("/home/iris-xport/cpp_qtcreator/ximeaImageRecorder-Release/ximeaImageRecorder", "r");ss
// fgets(buffer, sizeof(buffer), fp);
// printf("%s", buffer);
// pclose(fp);
int sockfd;
struct sockaddr_in server;
struct sockaddr_in client;
socklen_t addrlen;
int num;
char buf[MAXDATASIZE];
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("Creatingsocket failed.");
}
bzero(&server,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(PORT+1);
server.sin_addr.s_addr= htonl(INADDR_ANY);
if(bind(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1)
{
perror("Bind()error.");
}
addrlen=sizeof(client);
while (1)
{
//printf("PsdkTest_IrisRecordSystemChanged: record system status change! 8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888\n");
num =recvfrom(sockfd,buf,MAXDATASIZE,0,(struct sockaddr*)&client,&addrlen);
if (num < 0)
{
perror("recvfrom() error\n");
continue;
}
buf[num] = '\0';
printf("You got a message (%s) from client.\n",buf);
//printf("You got a message (%s%) from client.\nIt's ip is%s, port is %d.\n",buf,inet_ntoa(client.sin_addr),htons(client.sin_port));
char * result[2];
result[0] = strtok( buf, "," );
result[1] = strtok( NULL, "," );
if (strcmp(result[0],"sbg") == 0)
{
s_stateOfSbg = atoi(result[1]);
printf("sbg的状态为: %d\n\n", atoi(result[1]));
switch (s_stateOfSbg)
{
case 0:
s_strStateOfSbg="未打开";
break;
case 1:
s_strStateOfSbg="波特率设置失败";
break;
case 2:
s_strStateOfSbg="打开成功";
break;
case 3:
s_strStateOfSbg="采集中";
break;
default:
break;
}
}
else if (strcmp(result[0],"Accuracy") == 0)
{
s_strSbgAccuracy=result[1];
// s_sbgMagState = atoi(result[1]);
// switch (s_sbgMagState)
// {
// case 0:
// s_strSbgAccuracy="false";
// break;
// case 1:
// s_strSbgAccuracy="true";
// break;
// default:
// break;
// }
}
else if (strcmp(result[0],"SolutionMode") == 0)
{
s_sbgMagState = atoi(result[1]);
switch (s_sbgMagState)
{
case 0:
s_strSbgSolutionMode="UNINITIALIZED";
break;
case 1:
s_strSbgSolutionMode="VERTICAL_GYRO";
break;
case 2:
s_strSbgSolutionMode="AHRS";
break;
case 3:
s_strSbgSolutionMode="NAV_VELOCITY";
break;
case 4:
s_strSbgSolutionMode="NAV_POSITION";
break;
default:
break;
}
}
else if (strcmp(result[0],"mag") == 0)
{
s_sbgMagState = atoi(result[1]);
printf("磁场矫正状态为: %d\n\n", atoi(result[1]));
switch (s_sbgMagState)
{
case 0:
s_strSbgMagState="串口打开错误";
break;
case 1:
s_strSbgMagState="磁场矫正失败";
break;
case 2:
s_strSbgMagState="无法获取磁场数据";
break;
case 3:
s_strSbgMagState="磁场数据无效";
break;
case 4:
s_strSbgMagState="写入磁场数据失败";
break;
case 5:
s_strSbgMagState="POOR";
break;
case 6:
s_strSbgMagState="GOOD";
break;
case 7:
s_strSbgMagState="OPTIMAL";
break;
default:
break;
}
}
else if (strcmp(result[0],"ximea") == 0)
{
s_stateOfXimea = atoi(result[1]);
printf("ximea的状态为: %d\n\n", atoi(result[1]));
switch (s_stateOfXimea)
{
case 0:
s_strStateOfXimea="未打开";
break;
case 1:
s_strStateOfXimea="打开成功";
break;
case 2:
s_strStateOfXimea="帧率设置完成";
break;
case 3:
s_strStateOfXimea="自动曝光完成";
break;
case 4:
s_strStateOfXimea="正在采集";
break;
case 21:
s_strStateOfXimea="未处理错误";
break;
case 22:
s_strStateOfXimea="相机被占用";
break;
default:
break;
}
}
else if (strcmp(result[0],"file") == 0)
{
s_stateOfFile = atoi(result[1]);
printf("file的状态为: %d\n\n", atoi(result[1]));
switch (s_stateOfFile)
{
case 0:
s_strStateOfFile="等待拷贝数据";
break;
case 1:
s_strStateOfFile="正在拷贝";
break;
case 2:
s_strStateOfFile="没有数据可拷贝";
break;
case 3:
s_strStateOfFile="请插入u盘";
break;
default:
break;
}
}
}
}
#ifndef __CC_ARM
#pragma GCC diagnostic pop
#endif
static T_PsdkReturnCode PsdkTestWidget_SetWidgetValue(E_PsdkWidgetType widgetType, uint32_t index, int32_t value,
void *userData)
{
USER_UTIL_UNUSED(userData);
PsdkLogger_UserLogInfo("Set widget value, widgetType = %s, widgetIndex = %d ,widgetValue = %d",
s_widgetTypeNameArray[widgetType], index, value);
s_widgetValueList[index] = value;
return PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_PsdkReturnCode PsdkTestWidget_GetWidgetValue(E_PsdkWidgetType widgetType, uint32_t index, int32_t *value,
void *userData)
{
USER_UTIL_UNUSED(userData);
USER_UTIL_UNUSED(widgetType);
*value = s_widgetValueList[index];
return PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_PsdkReturnCode PsdkTestWidget_SetWidgetValue_StartRecord(E_PsdkWidgetType widgetType, uint32_t index, int32_t value,
void *userData)
{
USER_UTIL_UNUSED(userData);
PsdkLogger_UserLogInfo("Set widget value, widgetType = %s, widgetIndex = %d ,widgetValue = %d",
s_widgetTypeNameArray[widgetType], index, value);
s_widgetValueList[index] = value;
switch (index)
{
case 2:
if (value==0)//系统关闭
{
char* command = "2";
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
}
else if (value==1)//系统启动
{
char* command = "1";
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
}
break;
case 3:
if (value==0)//停止磁场矫正
{
char* command = "8,0";
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
//printf("ttttttttttttt\n");
}
else if (value==1)//开始磁场矫正
{
char* command = "8,1";
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
//printf("kkkkkkkkkkkkk\n");
}
break;
case 5://自动曝光
if (value==0)
{
;
}
else if (value==1)
{
char* command = "6";
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
}
break;
case 6://设置帧率
{
char command[50] = "5,";
char framerate[20];
sprintf(framerate,"%d",value);
strcat(command,framerate);
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
break;
}
case 8:
if (value==0)//停止采集
{
char* command = "4";
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
}
else if (value==1)//开始采集
{
char* command = "3";
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
}
break;
case 9:
if (value==0)//无操作
{
}
if (value==1)//拷贝数据
{
char* command = "7";
sendto(s_sockfd, command,strlen(command),0,(struct sockaddr *)&s_server,sizeof(s_server));
}
else if (value==2)//重启电脑
{
system("reboot");
}
else if (value==3)//关机
{
system("shutdown now");
}
break;
default:
break;
}
return PSDK_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/