1、操作遥控器按钮,psdk进程通过socket发送命令给相机进程 来控制高光谱采集系统;

2、通过FFmpeg采集摄像头视频流并编码为h264,利用psdk推流到遥控器;
This commit is contained in:
tangchao0503
2022-06-22 16:48:50 +08:00
commit 109e0a8f2b
89 changed files with 17079 additions and 0 deletions

View File

@ -0,0 +1,634 @@
/**
********************************************************************
* @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****/