Motor Control - Vraised3/e-vent GitHub Wiki

Welcome to the e-vent wiki!

Description

E-Vent is a library that enables input and control functionality of a Servo DC Motor to manipulate an arm to enable squeezing of an Ambu bag. It is designed for an Ambu bag respirator.

Hardware Specifications

  • Here we describe the core specifications of the motor and controller being used
  • The arm moves upto ~30 degrees

Motor

Model: Andy Mark AM 3656 188:1

Motor Movement

Position range: -100 to 700 clicks
Velocity range: 1800 clicks/s
Acceleration range: 200000 clicks/s^2

Controller

Model: BasicMicro RoboClaw Solo
reference: [http://downloads.basicmicro.com/docs/roboclaw_user_manual.pdf](Roboclaw User Manual)

Encoder

Measured in Clicks

Pneumatic Actuation Range

reference: Constants.h
RR: 10 to 35 BPM, @1 steps
IE: 1:1to4, @0.1 steps
Vol: 100 to 800 ml, @25 steps
AC: 2 to 5, @0.1 steps
PEEP Pause: 0.05 to 1.0 sec

Operation to Pneumatic Calculations

void calculateWaveform(){
    tPeriod = 60.0 / knobs.bpm(); // Cycle Period = 60 sec / RR
    tHoldIn = tPeriod / (1 + knobs.ie()); // 
    tIn = tHoldIn - HOLD_IN_DURATION;
    tEx = min(tHoldIn + MAX_EX_DURATION, tPeriod - MIN_PEEP_PAUSE);
}

Pneumatic Operation Defaults

Homing Volts: 30V
Homing Pause: 1.0 sec
Max Pressure: 40 cmH2O
Min Plateau Pressure: 5 cmH2O
Max Resist Pressure: 2.0
Min Tidal Pressure

Motor States

enum States {
DEBUG_STATE,       // 0
IN_STATE,          // 1
HOLD_IN_STATE,     // 2
EX_STATE,          // 3
PEEP_PAUSE_STATE,  // 4
HOLD_EX_STATE,     // 5
PREHOME_STATE,     // 6
HOMING_STATE,      // 7
OFF_STATE          // 8
};

Waveform

  |                                                                    
  |     |<- Inspiration ->|<- Expiration ->|                           
P |                                                                    
r |     |                 |                |                           
e |             PIP -> /                                  /            
s |     |             /|                   |             /|            
s |                  / |__  <- Plateau                  / |__          
u |     |           /     \                |           /     \         
r |                /       \                          /       \        
e |     |         /         \              |         /         \       
  |              /           \                      /           \      
  |     |       /             \            |       /             \     
  |            /               \                  /               \    
  |     |     /                 \          |     /                     
  |          /                   \              /                      
  |     |   /                     \        |   /                       
  |        /                       \          /                        
  |       /                         \        /                         
  | _____/                  PEEP ->  \______/                          
  |___________________________________________________________________ 
         |             |  |          |      |                          
         |<- tIn ----->|  |          |      |                   Time   
         |<- tHoldIn ---->|          |      |                          
         |<- tEx ------------------->|      |                          
         |<- tPeriod ---------------------->|                          
         |                                                             
                                                                       
     tCycleTimer                                                       

Software Specifications

Roboclaw Base

RoboClaw.cpp

bool RoboClaw::write_n(uint8_t cnt, ... )
{
	uint8_t trys=MAXRETRY;
	do{
		crc_clear();
		//send data with crc
		va_list marker;
		va_start( marker, cnt );     /* Initialize variable arguments. */
		for(uint8_t index=0;index<cnt;index++){
			uint8_t data = va_arg(marker, int);
			crc_update(data);
			write(data);
		}
		va_end( marker );              /* Reset variable arguments.      */
		uint16_t crc = crc_get();
		write(crc>>8);
		write(crc);
		if(read(timeout)==0xFF)
			return true;
	}while(trys--);
	return false;
}
bool RoboClaw::write_n(uint8_t cnt, ... )
{
	uint8_t trys=MAXRETRY;
	do{
		crc_clear();
		//send data with crc
		va_list marker;
		va_start( marker, cnt );     /* Initialize variable arguments. */
		for(uint8_t index=0;index<cnt;index++){
			uint8_t data = va_arg(marker, int);
			crc_update(data);
			write(data);
		}
		va_end( marker );              /* Reset variable arguments.      */
		uint16_t crc = crc_get();
		write(crc>>8);
		write(crc);
		if(read(timeout)==0xFF)
			return true;
	}while(trys--);
	return false;
}
bool RoboClaw::SpeedAccelDeccelPositionM1(uint8_t address,uint32_t accel,uint32_t speed,uint32_t deccel,uint32_t position,uint8_t flag){
	return write_n(19,address,M1SPEEDACCELDECCELPOS,SetDWORDval(accel),SetDWORDval(speed),SetDWORDval(deccel),SetDWORDval(position),flag);
}


Utilities.cpp

void goToPosition(const RoboClaw& roboclaw, const long& pos, const long& vel, const long& acc) {
    roboclaw.SpeedAccelDeccelPositionM1(ROBOCLAW_ADDR, acc, vel, acc, pos, 1); 
}
void goToPositionByDur(const RoboClaw& roboclaw, const long& goal_pos, const long& cur_pos, const float& dur) {
  if (dur <= 0) return; // Can't move in negative time

  const long dist = abs(goal_pos - cur_pos);
  long vel = round(2*dist/dur); // Try bang-bang control
  long acc = round(2*vel/dur); // Constant acc in and out
  if (vel > VEL_MAX) {
    // Must use trapezoidal velocity profile to clip at VEL_MAX
    vel = VEL_MAX;
    const float acc_dur = dur - dist/vel;
    acc = acc_dur > 0 ? round(vel/acc_dur) : ACC_MAX;
    acc = min(ACC_MAX, acc);
  }

  goToPosition(roboclaw, goal_pos, vel, acc);
}

distance = set_position - current_position velocity = 2 x (distance / duration)