Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • danc/MicroCART
  • snawerdt/MicroCART_17-18
  • bbartels/MicroCART_17-18
  • jonahu/MicroCART
4 results
Show changes
Showing
with 2916 additions and 42 deletions
This diff is collapsed.
This diff is collapsed.
#ifndef _COMMANDS_H
#define _COMMANDS_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "type_def.h"
// ----------------------
// Helper stuff
#define MAX_TYPE 6
#define MAX_SUBTYPE 100
enum Message{
BEGIN_CHAR = 0xBE,
END_CHAR = 0xED
};
// This should also have double to avoid confusion with float values.
enum DataType
{
floatType,
intType,
stringType
};
// MESSAGE SUBTYPES
struct MessageSubtype{
char ID;
char cmdText[100];
char cmdDataType;
int (*functionPtr)(unsigned char *command, int dataLen, modular_structs_t *structs);
};
// MESSAGE TYPES
struct MessageType{
char ID;
struct MessageSubtype subtypes[MAX_SUBTYPE];
};
int debug(unsigned char *c, int dataLen, modular_structs_t *structs);
int update(unsigned char *c, int dataLen, modular_structs_t *structs);
int logdata(unsigned char *c, int dataLen, modular_structs_t *structs);
int response(unsigned char *packet, int dataLen, modular_structs_t *structs);
int setyaw(unsigned char *c, int dataLen, modular_structs_t *structs);
int setyawp(unsigned char *c, int dataLen, modular_structs_t *structs);
int setyawd(unsigned char *c, int dataLen, modular_structs_t *structs);
int setroll(unsigned char *c, int dataLen, modular_structs_t *structs);
int setrollp(unsigned char *c, int dataLen, modular_structs_t *structs);
int setrolld(unsigned char *c, int dataLen, modular_structs_t *structs);
int setpitch(unsigned char *c, int dataLen, modular_structs_t *structs);
int setpitchp(unsigned char *c, int dataLen, modular_structs_t *structs);
int setpitchd(unsigned char *c, int dataLen, modular_structs_t *structs);
int setthrottle(unsigned char *c, int dataLen, modular_structs_t *structs);
int setthrottlep(unsigned char *c, int dataLen, modular_structs_t *structs);
int setthrottlei(unsigned char *c, int dataLen, modular_structs_t *structs);
int setthrottled(unsigned char *c, int dataLen, modular_structs_t *structs);
int getyaw(unsigned char *c, int dataLen, modular_structs_t *structs);
int getyawp(unsigned char *c, int dataLen, modular_structs_t *structs);
int getyawd(unsigned char *c, int dataLen, modular_structs_t *structs);
int getroll(unsigned char *c, int dataLen, modular_structs_t *structs);
int getrollp(unsigned char *c, int dataLen, modular_structs_t *structs);
int getrolld(unsigned char *c, int dataLen, modular_structs_t *structs);
int getpitch(unsigned char *c, int dataLen, modular_structs_t *structs);
int getpitchp(unsigned char *c, int dataLen, modular_structs_t *structs);
int getpitchd(unsigned char *c, int dataLen, modular_structs_t *structs);
int getthrottle(unsigned char *c, int dataLen, modular_structs_t *structs);
int getthrottlep(unsigned char *c, int dataLen, modular_structs_t *structs);
int getthrottlei(unsigned char *c, int dataLen, modular_structs_t *structs);
int getthrottled(unsigned char *c, int dataLen, modular_structs_t *structs);
int getaccel(unsigned char *c, int dataLen, modular_structs_t *structs);
int getgyro(unsigned char *c, int dataLen, modular_structs_t *structs);
int getpitchangle(unsigned char *c, int dataLen, modular_structs_t *structs);
int getrollangle(unsigned char *c, int dataLen, modular_structs_t *structs);
int respaccel(unsigned char *c, int dataLen, modular_structs_t *structs);
int respgyro(unsigned char *c, int dataLen, modular_structs_t *structs);
int resppitchangle(unsigned char *c, int dataLen, modular_structs_t *structs);
int resprollangle(unsigned char *c, int dataLen, modular_structs_t *structs);
int respyaw(unsigned char *c, int dataLen, modular_structs_t *structs);
int respyawp(unsigned char *c, int dataLen, modular_structs_t *structs);
int respyawd(unsigned char *c, int dataLen, modular_structs_t *structs);
int resproll(unsigned char *c, int dataLen, modular_structs_t *structs);
int resprollp(unsigned char *c, int dataLen, modular_structs_t *structs);
int resprolld(unsigned char *c, int dataLen, modular_structs_t *structs);
int resppitch(unsigned char *c, int dataLen, modular_structs_t *structs);
int resppitchp(unsigned char *c, int dataLen, modular_structs_t *structs);
int resppitchd(unsigned char *c, int dataLen, modular_structs_t *structs);
int respthrottle(unsigned char *c, int dataLen, modular_structs_t *structs);
int respthrottlep(unsigned char *c, int dataLen, modular_structs_t *structs);
int respthrottlei(unsigned char *c, int dataLen, modular_structs_t *structs);
int respthrottled(unsigned char *c, int dataLen, modular_structs_t *structs);
int respaccel(unsigned char *c, int dataLen, modular_structs_t *structs);
int respgyro(unsigned char *c, int dataLen, modular_structs_t *structs);
int resppitchangle(unsigned char *c, int dataLen, modular_structs_t *structs);
int resprollangle(unsigned char *c, int dataLen, modular_structs_t *structs);
float getFloat(unsigned char* str, int pos);
int getInt(unsigned char* str, int pos);
// TODO add in string to be read from the command line when sending a subtype of message
extern struct MessageType MessageTypes[MAX_TYPE];
#endif
\ No newline at end of file
#include "communication.h"
#include "commands.h"
#include <string.h>
#include <ctype.h>
static int msgNum = 0;
tokenList_t tokenize(char* cmd) {
int maxTokens = 16;
tokenList_t ret;
ret.numTokens = 0;
ret.tokens = malloc(sizeof(char*) * maxTokens);
ret.tokens[0] = NULL;
int i = 0;
char* token = strtok(cmd, " ");
while (token != NULL && i < maxTokens - 1) {
ret.tokens[i++] = token;
ret.tokens[i] = NULL;
ret.numTokens++;
token = strtok(NULL, " ");
}
return ret;
}
int checkFloat(char *floatString, float *value) {
char *tmp;
*value = strtod(floatString, &tmp);
if(!(isspace(*tmp) || *tmp == 0)) {
fprintf(stderr, "%s is not a valid floating-point number\n", floatString);
return 0;
}
return 1;
}
int checkInt(char *intString, int *value) {
char *tmp;
long temp_long;
temp_long = strtol(intString, &tmp, 0); // base 10 number inputted
if(temp_long < INT_MIN || temp_long > INT_MAX || !(isspace(*tmp) || *tmp == 0)) {
fprintf(stderr, "%s is not a valid integer number\n", intString);
return 0;
}
printf("temp: %ld\n\n", temp_long);
*value = (int) temp_long;
return 1;
}
//--------------------------------
// Ground Station
//--------------------------------
// Formatting commands from ground station CLI
int formatCommand(char *command, unsigned char **formattedCommand) {
//fprintf(stderr, "length = %li , received '%s'\n", strlen(command), command);
char cmd[strlen(command)];
strncpy(cmd, command, strlen(command));
cmd[strlen(command)] = '\0';
tokenList_t tokens = tokenize(cmd);
float floatValue = 0.0;
int intValue = 0;
int valid;
metadata_t metadata;
// ----------------------------------------------
if(tokens.numTokens > 0) {
for(int type = 0; type < MAX_TYPE; type++)
{
for(int subtype = 0; subtype < MAX_SUBTYPE; subtype++)
{
if(strcmp(tokens.tokens[0], MessageTypes[type].subtypes[subtype].cmdText) == 0)
{
printf("Sending\n\ttype: %d, \n\tsubtype: %d\n\tcommand: %s\n", type, subtype, MessageTypes[type].subtypes[subtype].cmdText);
// Make sure the second token is the right type
switch (MessageTypes[type].subtypes[subtype].cmdDataType)
{
// Validate the float input
case floatType:
metadata.begin_char = (char) BEGIN_CHAR;
metadata.msg_type = MessageTypes[type].ID;
metadata.msg_subtype = MessageTypes[type].subtypes[subtype].ID;
if(MessageTypes[type].ID == 0x01) {
valid = checkFloat(tokens.tokens[1], &floatValue);
if(!valid) {
return -1;
}
metadata.data_len = sizeof(floatValue);
} else {
metadata.data_len = 0;
}
metadata.msg_id = msgNum++;
formatPacket(&metadata, &floatValue, formattedCommand);
break;
// Validate the integer input
case intType:
metadata.begin_char = (char) BEGIN_CHAR;
metadata.msg_type = MessageTypes[type].ID;
metadata.msg_subtype = MessageTypes[type].subtypes[subtype].ID;
if(MessageTypes[type].ID == 0x01) {
valid = checkInt(tokens.tokens[1], &intValue);
if(!valid) {
return -1;
}
metadata.data_len = sizeof(intValue);
} else {
metadata.data_len = 0;
}
metadata.msg_id = msgNum++;
formatPacket(&metadata, &intValue, formattedCommand);
break;
// Validate the string input (doesn't need to happen)
case stringType:
metadata.begin_char = (char) BEGIN_CHAR;
metadata.msg_type = MessageTypes[type].ID;
metadata.msg_subtype = MessageTypes[type].subtypes[subtype].ID;
metadata.msg_id = msgNum++;
metadata.data_len = strlen(tokens.tokens[1]);
formatPacket(&metadata, &tokens.tokens[1], formattedCommand);
break;
default:
return -1;
}
return 0;
}
}
}
}
// Only gets here if the command does not exist
return -1;
}
// QUAD & Ground Station
// Format the log data from log_message
//int formatData(unsigned char *log_msg, unsigned char *formattedCommand)
int formatPacket(metadata_t *metadata, void *data, unsigned char **formattedCommand)
{
*formattedCommand = malloc(sizeof(unsigned char) * metadata->data_len + 8);
//----------------------------------------------------------------------------------------------
// index|| 0 | 1 | 2 | 3 & 4 | 5 & 6 | 7+ | end |
//---------------------------------------------------------------------------------------------|
// msg param|| beg char | msg type | msg subtype | msg id | data len (bytes) | data | checksum |
//-------------------------------------------------------------------------------------------- |
// bytes|| 1 | 1 | 1 | 2 | 2 | var | 1 |
//----------------------------------------------------------------------------------------------
// Begin Char:
(*formattedCommand)[0] = metadata->begin_char;
// Msg type:
(*formattedCommand)[1] = metadata->msg_type;
// Msg subtype
(*formattedCommand)[2] = metadata->msg_subtype;
//Msg id (msgNum is 2 bytes)
(*formattedCommand)[3] = (metadata->msg_id & 0x000000ff);
(*formattedCommand)[4] = ((metadata->msg_id >> 8) & 0x000000ff);
// Data length and data - bytes 5&6 for len, 7+ for data
(*formattedCommand)[5] = metadata->data_len & 0x000000ff;
(*formattedCommand)[6] = (metadata->data_len >> 8) & 0x000000ff;
memcpy(&((*formattedCommand)[7]), data, metadata->data_len);
// Checksum
// receive data and calculate checksum
int i;
char data_checksum;
for(i = 0; i < 7 + metadata->data_len; i++)
{
data_checksum ^= (*formattedCommand)[i];
}
(*formattedCommand)[7 + metadata->data_len] = data_checksum;
return 0;
}
// returns the length of the data in bytes (datalen from packet) and fills data
// and metadata with the packet information
// use as follows:
//
// packet is the entire packet message (formatted)
// data is an unallocated (char *) (pass it to this function as &data)
// meta_data is a pointer to an instance of metadata_t
//
int parse_packet(unsigned char * packet, unsigned char ** data, metadata_t * meta_data)
{
//----------------------------------------------------------------------------------------------
// index|| 0 | 1 | 2 | 3 & 4 | 5 & 6 | 7+ | end |
//---------------------------------------------------------------------------------------------|
// msg param|| beg char | msg type | msg subtype | msg id | data len (bytes) | data | checksum |
//-------------------------------------------------------------------------------------------- |
// bytes|| 1 | 1 | 1 | 2 | 2 | var | 1 |
//----------------------------------------------------------------------------------------------
// first byte must be the begin char
if(packet[0] != 0xBE)
return -1;
// receive metadata
meta_data->begin_char = packet[0];
meta_data->msg_type = packet[1];
meta_data->msg_subtype = packet[2];
meta_data->msg_id = (packet[4] << 8) | (packet[3]);
meta_data->data_len = (packet[6] << 8) | (packet[5]);
unsigned char packet_checksum = packet[7+meta_data->data_len];
//fprintf(stderr, "datalen: %d\n", meta_data->data_len);
int i;
// receive data
*data = malloc(meta_data->data_len);
for(i = 0; i < meta_data->data_len; i++)
{
(*data)[i] = packet[7+i];
}
// calculate checksum
unsigned char calculated_checksum = 0;
for(i = 0; i < meta_data->data_len + 7; i++)
{
calculated_checksum ^= packet[i];
}
// compare checksum
if(packet_checksum != calculated_checksum)
fprintf(stderr, "Checksums did not match (Parse Packet): 0x%02x\t0x%02x\n", packet_checksum, calculated_checksum);
return 0;
}
// QUAD & Ground Station
// Process the command received
int processCommand(unsigned char *packet, modular_structs_t *structs) {
int validPacket;
unsigned char *data;
metadata_t metadata;
// Validate the message is correctly formatted
validPacket = parse_packet(packet, &data, &metadata);
if(validPacket != 0) {
return -1;
}
if(metadata.data_len >= 0) {
/* Null check*/
if (MessageTypes[(unsigned char)metadata.msg_type].subtypes[
(unsigned char) metadata.msg_subtype].functionPtr) {
// Call the appropriate subtype function
(* (MessageTypes[(unsigned char)metadata.msg_type].subtypes[(unsigned char)metadata.msg_subtype].functionPtr))(data, metadata.data_len, structs);
}
return 0;
}
// Only gets here if there is an error
return -1;
}
#ifndef _COMMUNICATION_H
#define _COMMUNICATION_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include "type_def.h"
tokenList_t tokenize(char* cmd);
int checkFloat(char *floatString, float *value);
int checkInt(char *intString, int *value);
int formatCommand(char *command, unsigned char **formattedCommand);
int formatPacket(metadata_t *metadata, void *data, unsigned char **formattedCommand);
int parse_packet(unsigned char * packet, unsigned char ** data, metadata_t * meta_data);
int processCommand(unsigned char *command, modular_structs_t *structs);
int logData(unsigned char *log_msg, unsigned char *formattedCommand);
#endif
\ No newline at end of file
#ifndef __CONFIG_H
#define __CONFIG_H
#define DEFAULT_SOCKET "/var/run/ucart.socket"
#define SOCKET_ENV "UCART_SOCKET"
#define NOQUAD_ENV "UCART_NO_QUAD"
#define NOVRPN_ENV "UCART_NO_VRPN"
// If you are planning on using any of these env vars and you have
// exported them with normal user rights. You will need to run the
// backend with sudo elevation and with the --preserve-env flag or -E
#define QUAD_WIFI_ENV "UCART_USE_WIFI"
#define QUAD_IP_ENV "UCART_QUAD_IP"
#define QUAD_IP_DEFAULT "192.168.4.1"
#define QUAD_PORT_ENV "UCART_QUAD_PORT"
#define QUAD_PORT_DEFAULT 8080
#endif
This diff is collapsed.
......@@ -15,6 +15,7 @@
int createLogFile(int, char*);
int writeStringToLog(const char*);
int updateLogFile(const struct ucart_vrpn_TrackerData* );
void closeLogFile();
#endif
\ No newline at end of file
#endif
File moved
......@@ -23,13 +23,13 @@ extern "C"
#endif
struct ucart_vrpn_tracker;
struct ucart_vrpn_TrackerData {
double x;
double y;
double z;
float x;
float y;
float z;
double pitch;
double roll;
double yaw;
float pitch;
float roll;
float yaw;
double fps;
struct timeval timestamp;
......@@ -54,16 +54,19 @@ extern "C"
namespace microcart
{
struct TrackerData {
double x;
double y;
double z;
public:
float x;
float y;
float z;
double pitch;
double roll;
double yaw;
float pitch;
float roll;
float yaw;
double fps;
timeval timestamp;
TrackerData();
};
class Tracker {
......
# CLI
## Usage
The Cli has been designed to function similarly to command line programs. Run the program using ./Cli
To run a specific command in the
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.