Skip to content
Snippets Groups Projects
test_safety_checks.rb 4.09 KiB
Newer Older
#!/usr/bin/env ruby

# Safety Checks
#
# Startup the virtual quad and make sure it doesn't allow combinations of things
# that could hurt people.
THROTTLE_MIN = 110200
THROTTLE_MAX = 191900
THROTTLE_MID = (THROTTLE_MAX + THROTTLE_MIN)/2
THROTTLE_3_4 = (THROTTLE_MAX + THROTTLE_MID)/2
THROTTLE_QUAR = (THROTTLE_MID + THROTTLE_MIN)/2
THROTTLE_EIGHTH = (THROTTLE_QUAR + THROTTLE_MIN)/2
THROTTLE_16 = (THROTTLE_EIGHTH + THROTTLE_MIN)/2
MOTOR_MIN = 100000
MOTOR_MAX = 200000
GEAR_ON = 170800
GEAR_OFF = 118300
GRAVITY = 4096
MOTOR1 = "virt-quad-fifos/pwm-output-motor1"
MOTOR2 = "virt-quad-fifos/pwm-output-motor2"
MOTOR3 = "virt-quad-fifos/pwm-output-motor3"
MOTOR4 = "virt-quad-fifos/pwm-output-motor4"

GEAR = "virt-quad-fifos/pwm-input-gear"
THROTTLE = "virt-quad-fifos/pwm-input-throttle"

LED = "virt-quad-fifos/mio7-led"

I2C_MPU_ACCEL_X = "virt-quad-fifos/i2c-mpu-accel-x"
I2C_MPU_ACCEL_Y = "virt-quad-fifos/i2c-mpu-accel-y"
I2C_MPU_ACCEL_Z = "virt-quad-fifos/i2c-mpu-accel-z"

require 'test/unit/assertions'
require 'thread'
include Test::Unit::Assertions

$fifos = Hash.new

def read_fifo_num(f)
  if not $fifos.key?(f)
    $fifos[f] = File.open(f)
  end
  $fifos[f].read().chomp.split("\n").last.to_i
# Utility functions
def check_motors_are_off
  motor1 = read_fifo_num(MOTOR1)
  motor2 = read_fifo_num(MOTOR2)
  motor3 = read_fifo_num(MOTOR3)
  motor4 = read_fifo_num(MOTOR4)
  assert_operator motor1, :<=, THROTTLE_MIN
  assert_operator motor2, :<=, THROTTLE_MIN
  assert_operator motor3, :<=, THROTTLE_MIN
  assert_operator motor4, :<=, THROTTLE_MIN
def get_motor_averages
  motors = [[], [], [], []]
  for i in 0..100
    motors[0].push(read_fifo_num(MOTOR1))
    motors[1].push(read_fifo_num(MOTOR2))
    motors[2].push(read_fifo_num(MOTOR3))
    motors[3].push(read_fifo_num(MOTOR4))
    sleep 0.010
  end
  average = []
  average[0] = motors[0].inject(:+).to_f / motors[0].size
  average[1] = motors[1].inject(:+).to_f / motors[1].size
  average[2] = motors[2].inject(:+).to_f / motors[2].size
  average[3] = motors[3].inject(:+).to_f / motors[3].size
  average
end

def check_led(on)
  led = read_fifo_num(LED)
  assert_equal(led, on)
end

script_dir = File.expand_path(File.dirname(__FILE__))
bin_dir = script_dir + "/../../bin/"
Dir.chdir(bin_dir)

# Start virtual quad
quad = Process.spawn("./virt-quad")

sleep 1

#################
#  Begin Tests
#################

begin
  puts("beginning tests")
  
  # Set gravity
  File.write(I2C_MPU_ACCEL_Z, -1 * GRAVITY)
  puts("Check that motors are off at startup")
  check_motors_are_off

  puts("Check that LED is off at startup")
  puts("Check that increasing the throttle does nothing to motors")
  # (because gear is still off)
  for i in (THROTTLE_MIN..THROTTLE_MAX).step(1000)
    check_motors_are_off
    sleep 0.005
  end

  puts("Check that flipping gear to 1 while throttle is high does nothing")
  # (motors should still be off, LED should still be off)
  File.write(GEAR, GEAR_ON)
  sleep 0.015
  check_motors_are_off
  i = THROTTLE_MAX
  while i > THROTTLE_MID
    i -= 1000
    check_motors_are_off
    check_led 0
    sleep 0.005
  end

  # (swtich GEAR back to off and bring throttle off)
  File.write(GEAR, GEAR_OFF)
  File.write(THROTTLE, THROTTLE_MIN)
  puts("Check that the LED turns on when gear is flipped on")
  # (motors should still be off because our throttle is low)
  File.write(GEAR, GEAR_ON)
  check_led 1
  check_motors_are_off

  puts("Check that motors turn on")
  File.write(THROTTLE, THROTTLE_MID)
  averages = get_motor_averages
  average = (averages[0] + averages[1] + averages[2] + averages[3])/4
  puts averages, "(#{average})"
  assert average.between?(THROTTLE_EIGHTH, MOTOR_MAX)

  # Check that gear switch kills the motors
  # (and that light goes off)
  File.write(GEAR, GEAR_OFF)
  check_motors_are_off
  check_led 0

  # (Bring the RC throttle back down)
  File.write(THROTTLE, THROTTLE_MIN)

  # Check that we can resume flight
  File.write(GEAR, GEAR_ON)
  check_led 1

  sleep 1
  puts "All safety checks passed."

ensure

  Process.kill(9, quad)

end