Daemon applications crashes and freezes the USB connection but it works fine with a SITL simulation

Hi

I am developing a module that will subscribe to the attitude setpoint, store between 20 and 100 values and use them to calculate a new attitude setpoint that will get published on a different topic (I haven’t done the publishing part yet) Once the buffer is filled, it goes back to the first value and overwrites it with a new one. I start the application through the nsh console.

My code seems to run fine while on a SITL simulation with jMAVsim. I uploaded it to a pixracer and connected to the console through the USB port in the pixracer. However, when I try to run my application, the connection dies and then I cannot connect to the pixracer even if I turn it on and off. I have to unplug it for a couple of minutes and try again.

I have no idea what could be the problem. I do need my application to run at a high rate, so I don’t know if that could be causing problems. Should I add a sleep command inside the while loop? How short does this sleep period need to be? How big can I make my buffer considering it is an array of attitude setpoint structures?

Here is my code:


static bool thread_should_exit = false; /< daemon exit flag */
static bool thread_running = false; /
< daemon status flag */
static int _control_task; /**< Handle of daemon task / thread */

/**

  • daemon management function.
    */
    __EXPORT int att_command_proc_main(int argc, char *argv[]);

/**

  • Mainloop of daemon.
    */
    int att_command_proc_thread_main(int argc, char *argv[]);

/**

  • Print the correct usage.
    */
    static void usage(const char *reason);

static void
usage(const char *reason)
{
if (reason) {
warnx("%s\n", reason);
}

warnx("usage: att_command_proc {start|stop|status} [-p <additional params>]\n\n");

}

/**

  • The daemon app only briefly exists to start

  • the background job. The stack size assigned in the

  • Makefile does only apply to this management task.

  • The actual stack size should be set in the call

  • to task_create().
    */
    int att_command_proc_main(int argc, char *argv[])
    {
    if (argc < 2) {
    usage(“missing command”);
    return 1;
    }

    if (!strcmp(argv[1], “start”)) {

     if (thread_running) {
     	warnx("daemon already running\n");
     	/* this is not an error */
     	return 0;
     }
    
     thread_should_exit = false;
     _control_task = px4_task_spawn_cmd("att_command_proc",
     				 SCHED_DEFAULT,
     				 SCHED_PRIORITY_DEFAULT,
     				 2000,
     				 att_command_proc_thread_main,
     				 (argv) ? (char *const *)&argv[2] : (char *const *)NULL);
     return 0;
    

    }

    if (!strcmp(argv[1], “stop”)) {
    thread_should_exit = true;
    return 0;
    }

    if (!strcmp(argv[1], “status”)) {
    if (thread_running) {
    warnx("\trunning\n");

     } else {
     	warnx("\tnot started\n");
     }
    
     return 0;
    

    }

    usage(“unrecognized command”);
    return 1;
    }

int att_command_proc_thread_main(int argc, char *argv[])
{

warnx("[daemon] starting\n");

thread_running = true;

/*Variable declarations*/
int _v_att_sp_sub = orb_subscribe(ORB_ID(vehicle_attitude_setpoint));  //subscribe to attitude setpoint
orb_set_interval(_v_att_sp_sub,20);  //update every 20 ms
bool updated;
static uint64_t last_sample_time = 0;  //Initialize time in microseconds
float dt=(hrt_absolute_time()-last_sample_time)/1000000.0f;
float samplingInterval = 0.05f;

struct vehicle_attitude_setpoint_s _v_att_sp;

/*Initialize buffer*/
int bufferSize=20;
struct vehicle_attitude_setpoint_s _v_att_sp_proc_buffer[bufferSize];
memset(&_v_att_sp_proc_buffer,0,sizeof(_v_att_sp_proc_buffer));
int procIndex =0;

/*Initialize attitude setpoint to publish*/
struct vehicle_attitude_setpoint_s _v_att_sp_proc;
memset(&_v_att_sp_proc,0,sizeof(_v_att_sp_proc));

/*Initialize processing parameters*/	
double A1=0,A2=0,t2=0;
double K,tau;


/*Calculate processing*/
K=1;
tau=0.1;
A1=1/(1+K);
A2=K/(1+K);
t2=tau/2;
int count = 0;

while (!thread_should_exit) {
	orb_check(_v_att_sp_sub,&updated);

	if(updated){
		orb_copy(ORB_ID(vehicle_attitude_setpoint),_v_att_sp_sub,&_v_att_sp);
	}

	dt=(hrt_absolute_time()-last_sample_time)/1000000.0f;
	
	if (dt>=samplingInterval){
		_v_att_sp_proc_buffer[procIndex].roll_body=_v_att_sp_proc_buffer[procIndex].roll_body+_v_att_sp.roll_body*(float)A1;
		_v_att_sp_proc_buffer[(procIndex+(int)(t2/(double)samplingInterval))%(bufferSize-1)].roll_body=_v_att_sp.roll_body*(float)A2;
		_v_att_sp_proc=_v_att_sp_proc_buffer[procIndex];

		memset(&_v_att_sp_proc_buffer[procIndex],0,sizeof(_v_att_sp_proc_buffer[procIndex]));
		

		if(procIndex+1<bufferSize-1)
		{
			procIndex++;
		}
		else
		{
			procIndex=0;
		}

	last_sample_time = hrt_absolute_time();

	//Print processed value to screen		
	count++;
	if (count == 4){
	count = 0;
	PX4_INFO("Roll: %f\tprocRoll: %f",(double)_v_att_sp.roll_body,(double)_v_att_sp_proc.roll_body);
	}
	}
}

warnx("[daemon] exiting.\n");

thread_running = false;

return 0;

}

Fixed this by using simple arrays instead of an array structure. I think it was a memory issue with my original code.