Something went wrong on our end
log_data.c 5.65 KiB
/*
* log_data.c
*
* Created on: Feb 20, 2016
* Author: ucart
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "PID.h"
#include "type_def.h"
#include "log_data.h"
#include "communication.h"
#include "computation_graph.h"
#include "node_pid.h"
#include "node_constant.h"
#include "node_mixer.h"
// Current index of the log array
int arrayIndex = 0;
// Size of the array
int arraySize = LOG_STARTING_SIZE;
struct graph_tuple { // Tuple for
int block_id;
int sub_id;
};
struct graph_tuple log_outputs[MAX_LOG_NUM];
struct graph_tuple log_params[MAX_LOG_NUM];
size_t n_outputs;
size_t n_params;
float* logArray;
int row_size;
void addOutputToLog(log_t* log_struct, int controller_id, int output_id) {
if (n_outputs < MAX_LOG_NUM) {
log_outputs[n_outputs].block_id = controller_id;
log_outputs[n_outputs].sub_id = output_id;
n_outputs++;
}
}
void addParamToLog(log_t* log_struct, int controller_id, int param_id) {
if (n_params < MAX_LOG_NUM) {
log_params[n_params].block_id = controller_id;
log_params[n_params].sub_id = param_id;
n_params++;
}
}
void initialize_logging(log_t* log_struct, parameter_t* ps) {
addOutputToLog(log_struct, ps->alt_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->x_pos_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->y_pos_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->pitch_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->roll_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->yaw_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->pitch_r_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->roll_r_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->yaw_r_pid, PID_CORRECTION);
addOutputToLog(log_struct, ps->cur_pitch, CONST_VAL);
addOutputToLog(log_struct, ps->cur_roll, CONST_VAL);
addOutputToLog(log_struct, ps->cur_yaw, CONST_VAL);
addOutputToLog(log_struct, ps->vrpn_x, CONST_VAL);
addOutputToLog(log_struct, ps->vrpn_y, CONST_VAL);
addOutputToLog(log_struct, ps->vrpn_alt, CONST_VAL);
addOutputToLog(log_struct, ps->vrpn_pitch, CONST_VAL);
addOutputToLog(log_struct, ps->vrpn_roll, CONST_VAL);
addOutputToLog(log_struct, ps->x_set, CONST_VAL);
addOutputToLog(log_struct, ps->y_set, CONST_VAL);
addOutputToLog(log_struct, ps->alt_set, CONST_VAL);
addOutputToLog(log_struct, ps->mixer, MIXER_PWM0);
addOutputToLog(log_struct, ps->mixer, MIXER_PWM1);
addOutputToLog(log_struct, ps->mixer, MIXER_PWM2);
addOutputToLog(log_struct, ps->mixer, MIXER_PWM3);
// TODO: Make this not stupid. Adding 6 for IMU and 1 for timestamp
row_size = n_outputs + n_params + 6 + 1;
size_t needed_memory = sizeof(float) * row_size * LOG_STARTING_SIZE;
logArray = malloc(needed_memory);
if (!logArray) { // malloc failed
arraySize = 0;
}
}
int log_data(log_t* log_struct, parameter_t* ps)
{
if(arrayIndex >= arraySize)
{
return 1;
}
float* thisRow = &logArray[arrayIndex * row_size * sizeof(float)];
int offset = 0;
thisRow[offset++] = log_struct->time_stamp;
thisRow[offset++] = log_struct->gam.accel_x;
thisRow[offset++] = log_struct->gam.accel_y;
thisRow[offset++] = log_struct->gam.accel_z;
thisRow[offset++] = log_struct->gam.gyro_xVel_p;
thisRow[offset++] = log_struct->gam.gyro_yVel_q;
thisRow[offset++] = log_struct->gam.gyro_zVel_r;
int i;
for (i = 0; i < n_params; i++) {
thisRow[offset++] = graph_get_param_val(ps->graph, log_params[i].block_id, log_params[i].sub_id);
}
for (i = 0; i < n_outputs; i++) {
thisRow[offset++] = graph_get_output(ps->graph, log_outputs[i].block_id, log_outputs[i].sub_id);
}
arrayIndex++;
return 0;
}
/**
* Prints all the log information.
*
* TODO: This should probably be transmitting in binary instead of ascii
*/
void printLogging(hardware_t *hardware_struct, log_t* log_struct, parameter_t* ps){
if (arrayIndex == 0) {
// Don't send any logs if nothing was logged
return;
}
int i;//, j;
char buf[2048] = {};
buf[0] = 0; // Mark buffer as size 0
char header1[256] = {};
char header2[1024] = {};
// Let user know that allocation failed
if (arraySize != LOG_STARTING_SIZE) {
size_t send_len = sprintf(header1, "Failed to allocate enough log memory\n");
send_data(LOG_ID, 0, header1, send_len);
return;
}
sprintf(header1, "time,accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z");
int end = 0;
// Print all the recorded block parameters
for (i = 0; i < n_params; i++) {
const char* block_name = ps->graph->nodes[log_params[i].block_id].name;
const char* output_name = ps->graph->nodes[log_params[i].block_id].type->param_names[log_params[i].sub_id];
end += sprintf(&header2[end], ",%s-%s", block_name, output_name);
}
// Print all the recorded block outputs
for (i = 0; i < n_outputs; i++) {
const char* block_name = ps->graph->nodes[log_outputs[i].block_id].name;
const char* param_name = ps->graph->nodes[log_outputs[i].block_id].type->output_names[log_outputs[i].sub_id];
end += sprintf(&header2[end], ",%s-%s", block_name, param_name);
}
end += sprintf(&header2[end], "\n");
strcat(buf,header1);
strcat(buf,header2);
send_data(&hardware_struct->uart, LOG_ID, 0, buf, strlen(buf));
/*************************/
/* print & send log data */
for(i = 0; i < arrayIndex; i++){
int size = format_log(i, log_struct, buf);
send_data(&hardware_struct->uart, LOG_ID, 0, buf, size);
}
char data[1] = {0}; // 1 byte to make compilers happy
send_data(LOG_END_ID, 0, data, 0);
}
void resetLogging() {
arrayIndex = 0;
}
int format_log(int idx, log_t* log_struct, char* buf) {
int i;
int end = 0;
float* row = &logArray[idx * row_size * sizeof(float)];\
end += sprintf(&buf[end], "%f", row[0]);
for (i = 1; i < row_size; i++) {
end += sprintf(&buf[end], ",%f", row[i]);
}
end += sprintf(&buf[end], "\n");
return end;
}