我正在为主动假肢设计新的硬件。我的系统有一台BeagleBone黑RevC嵌入式计算机和一些定制板。Debian ( BeagleBone Black )运行Debian。
我编写了一个C控制台应用程序来与来自Linux的其他板进行对话。从终端,我可以发送命令,如"./plan execute_1 set_pid_gains 10 50 0“,以改变在我的电机驱动器上运行的控制回路的增益。"plan“函数是用C编写的,它通过SPI发送消息。
该程序本身工作良好,我可以发送所有我想要的命令。然而,当我们开始从Python (使用Popen调用C程序)测试它时,我们意识到它的执行速度没有我们想要的那么快。
为了复制和隔离这个问题,我编写了一个shell脚本(fxa_test_z_1),它在我的网络上发送3个命令:
#!/bin/bash
# Places FlexSEA in Impedance control mode
# Use with care!
# Set control mode to 'z' (4)
./plan execute_1 set_control 4
# Current loop gains:
./plan execute_1 set_current_gains 10 50 0
# Choose from one of these:
./plan execute_1 set_z_gains 1 0 0
echo "FlexSEA in Stiffness mode"每个功能之间有一个14毫秒的延迟(用示波器测量)。我做了许多小实验来隔离这个问题。打开和关闭SPI端口、发送SPI命令和解析agv[]不是问题。如果我在同一个程序中多次调用它们,那么每个串行数据包之间的延迟顺序是700 is。
调用“尼斯-n -19 ./fxa_test_z_1”没有改变任何事情。
==
我能做些什么使这些函数调用发生得更快?我有希望让他们去分局吗?
现在,我试图避免对代码进行重大修改,因为我们希望明天测试我们的控制循环。
谢谢!
杰夫
发布于 2014-08-13 00:57:32
通过让plan在必须再次运行之前做更多的工作,可以使它更快。启动一个过程是一项很大的工作,所以你不想做的太多了。
要让plan做更多的工作,您可以在stdin上或从文件中向它提供命令列表。然后,棘手的部分是解析每一行以提取单个命令和参数。由于现有代码已经从argv读取命令,所以使用strtok很容易将命令解析为类似argv的数组。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COMMAND_LEN 256
#define MAX_ARGS 64
char *fake_argv[MAX_ARGS]; /* For compatibility with existing parser. */
const char *delims = " \n";
int main(int argc, char *argv[])
{
char command[MAX_COMMAND_LEN];
while( fgets(command, sizeof(command), stdin) )
{
int fake_argc = 0;
fake_argv[fake_argc] = strtok(command, delims);
while( fake_argv[fake_argc] != NULL )
{
fake_argv[++fake_argc] = strtok(NULL, delims);
}
{ int i; /* debug print... you can remove this block */
printf("Handling command: [%s], argc %d\n", command, fake_argc);
for( i = 0; i < fake_argc; ++i ) { printf(" arg: [%s]\n", fake_argv[i]); }
}
/* ... do the stuff you were already doing except now with fake_argv */
}
return 0;
}那么bash脚本就可以是一组提供给程序的行:
./plan << END_COMMAND_LIST
execute_1 set_control 4
execute_1 set_current_gains 10 50 0
execute_1 set_z_gains 1 0 0
END_COMMAND_LIST现在,plan进程只创建一次,并在退出之前运行3个命令。
发布于 2014-08-13 21:56:43
我将indiv的代码与main()合并,它可以工作,我可以每760‘s发送新命令(比以前快18倍!)
我的代码可能不那么优雅,但其他代码可能受益于一个完整的解决方案,因此如下所示:
//****************************************************************************
// main: FlexSEA Plan project: console app to control FlexSEA slaves
//****************************************************************************
//****************************************************************************
// Include(s)
//****************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../inc/flexsea_console.h"
#include "../inc/plan_spi.h"
#include "flexsea_local.h"
//****************************************************************************
// Local variable(s) & definitions
//****************************************************************************
int analog0 = 0;
//Choose between single multiple commands console app:
//#define SINGLE_COMMAND
#define MULTIPLE_COMMANDS
#ifdef SINGLE_COMMAND
#ifdef MULTIPLE_COMMANDS
#error "Pick one Command option!"
#endif
#endif
#define MAX_COMMAND_LEN 256
#define MAX_ARGS 8
char *fake_argv[MAX_ARGS];
const char *delims = " \n";
//****************************************************************************
// External variable(s)
//****************************************************************************
extern unsigned char execute_1_data[];
//****************************************************************************
// Function(s)
//****************************************************************************
int main(int argc, char *argv[])
{
#ifdef MULTIPLE_COMMANDS
char command[MAX_COMMAND_LEN];
char string1[20], string2[20] = "quit";
char default_argv[] = "";
int i = 0;
#endif //MULTIPLE_COMMANDS
//Open SPI:
flexsea_spi_open();
#ifdef MULTIPLE_COMMANDS
while(fgets(command, sizeof(command), stdin))
{
int fake_argc = 1;
//Fills fake_argv with empty strings to avoid sending old values with new commands
for(i = 0; i < MAX_ARGS; i++)
{
fake_argv[i] = default_argv;
}
//First argument
fake_argv[fake_argc] = strtok(command, delims);
//Other arguments
while( fake_argv[fake_argc] != NULL )
{
fake_argv[++fake_argc] = strtok(NULL, delims);
}
//Enable for terminal debug only:
/*
for(i = 0; i < MAX_ARGS; i++)
{
printf("fake_argv[%i] = %s\n", i, fake_argv[i]);
}
*/
//Do we want to exit? (exit when "quit" is received)
strcpy(string1, fake_argv[1]);
if(!strcmp(string1, string2))
{
printf("Quitting.\n");
break;
}
else
{
//Parser for console commands:
flexsea_console_parser(fake_argc, fake_argv);
//Can we decode what we received?
decode_spi_rx();
}
}
#endif //MULTIPLE_COMMANDS
#ifdef SINGLE_COMMAND
//Parser for console commands:
flexsea_console_parser(argc, argv);
//Can we decode what we received?
decode_spi_rx();
#endif //SINGLE_COMMAND
//Close SPI:
flexsea_spi_close();
return 0;
}我的测试shell脚本是:
#!/bin/bash
# How quickly can we send serial commands?
./plan << END_COMMAND_LIST
execute_1 set_leds 0 255 0 0
execute_1 set_leds 0 255 0 0
execute_1 set_leds 0 255 0 0
execute_1 set_leds 0 255 0 0
execute_1 set_leds 0 255 0 0
END_COMMAND_LIST非常感谢你的帮助!
杰夫
https://stackoverflow.com/questions/25275941
复制相似问题