Skip to content
Snippets Groups Projects
Commit fae32b06 authored by bbartels's avatar bbartels
Browse files

quad: improve virtual quad cli

parent 66942ac7
No related branches found
No related tags found
No related merge requests found
...@@ -16,7 +16,7 @@ Timeout::timeout(30) { ...@@ -16,7 +16,7 @@ Timeout::timeout(30) {
puts("Setting up...") puts("Setting up...")
# Start virtual quad # Start virtual quad
quad_pid = Process.spawn("./virt-quad -q", quad_pid = Process.spawn("./virt-quad start -q",
{ :rlimit_as => 536870912, # 512 MiB total RAM { :rlimit_as => 536870912, # 512 MiB total RAM
:rlimit_stack => 1048576}) # 1 MiB stack :rlimit_stack => 1048576}) # 1 MiB stack
...@@ -49,7 +49,7 @@ Timeout::timeout(30) { ...@@ -49,7 +49,7 @@ Timeout::timeout(30) {
# Send a debug command # Send a debug command
Thread.new { Thread.new {
sleep 0.1 sleep 0.5
send_packet [0xBE, 1, 0, 0, 0, 0, 0, 0xBF] send_packet [0xBE, 1, 0, 0, 0, 0, 0, 0xBF]
} }
...@@ -58,7 +58,7 @@ Timeout::timeout(30) { ...@@ -58,7 +58,7 @@ Timeout::timeout(30) {
# Receive the header # Receive the header
msg = [] msg = []
for i in 1..7 for i in 1..7
sleep 0.0001 sleep 0.01
c = fifo.read(1) c = fifo.read(1)
msg.push(c) msg.push(c)
end end
...@@ -68,7 +68,7 @@ Timeout::timeout(30) { ...@@ -68,7 +68,7 @@ Timeout::timeout(30) {
msg = [] msg = []
for i in 1..length for i in 1..length
sleep 0.0001 sleep 0.01
c = fifo.read(1) c = fifo.read(1)
msg.push(c) msg.push(c)
end end
......
...@@ -16,7 +16,7 @@ Timeout::timeout(30) { ...@@ -16,7 +16,7 @@ Timeout::timeout(30) {
puts("Setting up...") puts("Setting up...")
# Start virtual quad # Start virtual quad
quad_pid = Process.spawn("./virt-quad -q", quad_pid = Process.spawn("./virt-quad start -q",
{ :rlimit_as => 536870912, # 512 MiB total RAM { :rlimit_as => 536870912, # 512 MiB total RAM
:rlimit_stack => 1048576}) # 1 MiB stack :rlimit_stack => 1048576}) # 1 MiB stack
...@@ -83,7 +83,7 @@ Timeout::timeout(30) { ...@@ -83,7 +83,7 @@ Timeout::timeout(30) {
# Get logs # Get logs
Thread.new { Thread.new {
sleep 0.5 sleep 1
puts("Swiching off GEAR...") puts("Swiching off GEAR...")
set_gear GEAR_OFF set_gear GEAR_OFF
} }
......
...@@ -14,7 +14,7 @@ Dir.chdir(bin_dir) ...@@ -14,7 +14,7 @@ Dir.chdir(bin_dir)
puts("Firing up the quad...") puts("Firing up the quad...")
# Start virtual quad # Start virtual quad
quad = Process.spawn("valgrind --leak-check=full --log-file=./valgrind.out ./virt-quad") quad = Process.spawn("valgrind --leak-check=full --log-file=./valgrind.out ./virt-quad start")
sleep 1.5 sleep 1.5
......
...@@ -17,7 +17,7 @@ Timeout::timeout(60) { ...@@ -17,7 +17,7 @@ Timeout::timeout(60) {
puts("Setting up...") puts("Setting up...")
# Start virtual quad # Start virtual quad
quad_pid = Process.spawn("./virt-quad -q", quad_pid = Process.spawn("./virt-quad start -q",
{ :rlimit_as => 536870912, # 512 MiB total RAM { :rlimit_as => 536870912, # 512 MiB total RAM
:rlimit_stack => 1048576}) # 1 MiB stack :rlimit_stack => 1048576}) # 1 MiB stack
......
...@@ -8,17 +8,18 @@ plethoria of things required for flight in Coover 3050. In fact, you don't ...@@ -8,17 +8,18 @@ plethoria of things required for flight in Coover 3050. In fact, you don't
even have to be in Coover 3050... even have to be in Coover 3050...
# Using the Virtual Quad # Using the Virtual Quad
Start it up: The virt-quad has help output. Get started with:
``` ```
make run ./virt-quad
``` ```
And you can do things with it. You'll notice it will make a bunch of FIFOs in ## Using the UART Driver
the current directory. Write to / read from these FIFOs as you see fit.
## Writing to FIFO from shell The UART interface is implemented with unix FIFOs. You can treat these FIFOs
as regular unix files. Read from uart-tx to hear with the quad is saying. Write
to uart-rx to tell the quad something.
``` ```
echo "170000" > virt-quad-fifos/pwm-input-gear # Setting the gear to '1' echo "hello world" > virt-quad-fifos/uart-rx
cat virt-quad-fifos/pwm-output-motor1 # Read the motor 1 pwm signal cat virt-quad-fifos/uart-tx
``` ```
\ No newline at end of file
...@@ -4,15 +4,28 @@ ...@@ -4,15 +4,28 @@
#include "quad_app.h" #include "quad_app.h"
#include <fcntl.h> #include <fcntl.h>
struct VirtQuadIO *virt_quad_io;
int virt_quad_io_file_descriptor;
enum CLISubCommand {
START,
GET,
SET,
USAGE,
HELP,
};
int start_virt_quad(char *argv[]);
int handle_io_output(const char *name); int handle_io_output(const char *name);
int handle_io_input(const char *name, const char *value_str); int handle_io_input(const char *name, const char *value_str);
void set_shm(float value, float *dest, pthread_mutex_t *lock); void set_shm(float value, float *dest, pthread_mutex_t *lock);
void print_shm_float(float *value, pthread_mutex_t *lock); void print_shm_float(float *value, pthread_mutex_t *lock);
void print_shm_int(int *value, pthread_mutex_t *lock); void print_shm_int(int *value, pthread_mutex_t *lock);
void usage(char *executable_name); void usage(char *executable_name);
enum CLISubCommand parse_sub_command(char *argv[]);
struct VirtQuadIO *virt_quad_io; void open_new_shm_io();
int virt_quad_io_file_descriptor; void open_existing_shm_io();
void help_sub_command(char *argv[]);
/** /**
* Implement each of the hardware interfaces. * Implement each of the hardware interfaces.
...@@ -33,61 +46,91 @@ int setup_hardware(hardware_t *hardware) { ...@@ -33,61 +46,91 @@ int setup_hardware(hardware_t *hardware) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int fd; enum CLISubCommand sub_command = parse_sub_command(argv + 1);
switch (sub_command) {
case START:
open_new_shm_io();
start_virt_quad(argv + 2); // will block
break;
case SET:
open_existing_shm_io();
handle_io_input(argv[2], argv[3]);
break;
case GET:
open_existing_shm_io();
handle_io_output(argv[2]);
break;
case HELP:
help_sub_command(argv);
break;
case USAGE:
usage(argv[0]);
break;
}
// Decide if we are launching the quad or parsing arguments return 0;
if (argv[1] == NULL || strcmp(argv[1], "-q") == 0) { }
// launch the quad
enum CLISubCommand parse_sub_command(char *argv[]) {
// Allow making the quad quiet if (argv[0] == NULL) {
if (argv[1] != NULL && strcmp(argv[1], "-q") == 0) { return USAGE;
fd = open("/dev/null", O_WRONLY); }
close(STDOUT_FILENO); else if (strcmp(argv[0], "start") == 0) {
dup2(STDOUT_FILENO, fd); return START;
} }
else if (strcmp(argv[0], "help") == 0) {
// Prepare the shared memory for io. Clear memory and initialize. return HELP;
int *fd = &virt_quad_io_file_descriptor; }
*fd = shm_open(VIRT_QUAD_SHARED_MEMORY, O_CREAT | O_RDWR | O_TRUNC, 0666); else if (strcmp(argv[0], "get") == 0 && argv[1] != NULL) {
ftruncate(*fd, sizeof(struct VirtQuadIO)); return GET;
virt_quad_io = mmap(NULL, sizeof(struct VirtQuadIO), PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0); }
pthread_mutexattr_t attr; else if (strcmp(argv[0], "set") == 0 && argv[1] != NULL && argv[2] != NULL) {
pthread_mutexattr_init(&attr); return SET;
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&virt_quad_io->led_lock, &attr);
pthread_mutex_init(&virt_quad_io->motors_lock, &attr);
pthread_mutex_init(&virt_quad_io->rc_lock, &attr);
} }
else { else {
// parse command line arguments return USAGE;
}
}
// Open exising shared memory for io. DO NOT CLEAR. int start_virt_quad(char *argv[]) {
int *fd = &virt_quad_io_file_descriptor; int fd;
*fd = shm_open(VIRT_QUAD_SHARED_MEMORY, O_CREAT | O_RDWR, 0666);
virt_quad_io = mmap(NULL, sizeof(struct VirtQuadIO), PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) { // Allow making the quad quiet
usage(argv[0]); if (argv[0] != NULL && strcmp(argv[0], "-q") == 0) {
exit(0); fd = open("/dev/null", O_WRONLY);
} close(STDOUT_FILENO);
else if (strcmp(argv[1], "get") == 0 && argv[2] != NULL) { dup2(STDOUT_FILENO, fd);
handle_io_output(argv[2]);
}
else if (strcmp(argv[1], "set") == 0 && argv[2] != NULL && argv[3] != NULL) {
handle_io_input(argv[2], argv[3]);
}
else {
puts("Error in parsing commands");
usage(argv[0]);
}
return 0;
} }
puts("Starting the quad application"); puts("Starting the virtual quad.");
puts("Open another tab to query and control the virt quad, using the get and set commands.");
quad_main(setup_hardware); quad_main(setup_hardware);
return 0; return 0;
} }
void open_new_shm_io() {
// Prepare the shared memory for io. Clear memory and initialize.
int *fd = &virt_quad_io_file_descriptor;
*fd = shm_open(VIRT_QUAD_SHARED_MEMORY, O_CREAT | O_RDWR | O_TRUNC, 0666);
ftruncate(*fd, sizeof(struct VirtQuadIO));
virt_quad_io = mmap(NULL, sizeof(struct VirtQuadIO), PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&virt_quad_io->led_lock, &attr);
pthread_mutex_init(&virt_quad_io->motors_lock, &attr);
pthread_mutex_init(&virt_quad_io->rc_lock, &attr);
}
void open_existing_shm_io() {
// Open exising shared memory for io. DO NOT CLEAR.
int *fd = &virt_quad_io_file_descriptor;
*fd = shm_open(VIRT_QUAD_SHARED_MEMORY, O_CREAT | O_RDWR, 0666);
virt_quad_io = mmap(NULL, sizeof(struct VirtQuadIO), PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
}
/** /**
* The user wants to read an output by name. Get the output * The user wants to read an output by name. Get the output
* and print to stdout. * and print to stdout.
...@@ -203,25 +246,79 @@ void print_shm_int(int *value, pthread_mutex_t *lock) { ...@@ -203,25 +246,79 @@ void print_shm_int(int *value, pthread_mutex_t *lock) {
} }
void usage(char *executable_name) { void usage(char *executable_name) {
printf("Usage: %s [ -h | --help | -q ] [ command ]\n", executable_name); printf("Usage: %s command [ args ]\n", executable_name);
puts("Overview:"); puts("Overview:");
puts(" The virtual quad emulates the behavior of the real quad in the Unix"); puts(" The virtual quad emulates the behavior of the real quad in the Unix");
puts(" environment. Start the virtual quad in one tab (no arguments), and"); puts(" environment. Start the virtual quad in one tab (no arguments), and");
puts(" then control the I/O of the quad through commands."); puts(" then control the I/O of the quad through commands.");
puts("");
puts(" For help on a particular command, pass the command name to the help command");
puts(" Example:");
printf(" %s help get\n", executable_name);
puts("");
puts("Commands:"); puts("Commands:");
puts(" get output"); puts(" help");
puts(" set input value"); puts(" get");
puts("Outpus:"); puts(" set");
puts(" led"); puts(" start");
puts(" motors"); puts("");
puts("Inputs:"); }
puts(" rc_gear");
puts(" rc_flap"); void help_sub_command(char *argv[]) {
puts(" rc_throttle"); if (argv[2] == NULL) {
puts(" rc_pitch"); usage(argv[0]);
puts(" rc_roll"); }
puts(" rc_yaw"); else if (strcmp(argv[2], "help") == 0) {
puts("Examples:"); puts("Really?");
printf(" %s get led # prints 0 or 1 to stdout\n", executable_name); }
printf(" in%s set rc_gear 1 # sets gear to \"on\" \n", executable_name); else if (strcmp(argv[2], "get") == 0) {
printf("Usage: %s get output_name\n", argv[0]);
puts("");
puts(" Get an output on the virtual quad, specified by its output_name, and print");
puts(" to stdout");
puts("");
puts(" Possible output names");
puts(" led");
puts(" motor1");
puts(" motor2");
puts(" motor3");
puts(" motor4");
puts("");
}
else if (strcmp(argv[2], "set") == 0) {
printf("Usage: %s set input_name val\n", argv[0]);
puts("");
puts(" Set the value of an input on the quad, specified by its input_name");
puts("");
puts(" Possible input names");
puts(" rc_throttle");
puts(" rc_pitch");
puts(" rc_roll");
puts(" rc_yaw");
puts(" rc_gear");
puts(" rc_flap");
puts(" i2c_imu_x");
puts(" i2c_imu_y");
puts(" i2c_imu_z");
puts(" i2c_imu_p");
puts(" i2c_imu_q");
puts(" i2c_imu_r");
puts(" i2c_imu_mag_x");
puts(" i2c_imu_mag_y");
puts(" i2c_imu_mag_z");
puts("");
}
else if (strcmp(argv[2], "start") == 0) {
printf("Usage: %s start [ -q ]\n", argv[0]);
puts("");
puts(" Start the virtual quad. Exit using ctrl-c. In order to get and set I/O,");
puts(" you'll need to open another tab.");
puts("");
puts(" Flags");
puts(" q - Keep the quad quiet; don't print logs to the stdout");
puts("");
}
else {
usage(argv[0]);
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment