Go to Post It's a process of elimination led by inspiration. - JaneYoung [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 17-02-2007, 02:17
brennerator brennerator is offline
Registered User
#1560
 
Join Date: Jan 2005
Location: Silicon Valley
Posts: 75
brennerator is an unknown quantity at this point
Holding a position in our arm

Heres the deal:

We have a revolute double jointed arm; say we wnat to hold the lower portion of the arm in one place; how would we do so?

We have a potentiometer mesaureing the position values of the arm. Lets say we want the arm at a target val of 180. The arm is plugged into pwm02. We made some simple if/then statements...

Please ignore syntax.

sensor = Get_Analog_Value(rc_ana_in02);
targetval = 180;
if (sensor < targetval)
{
pwm02 = (127 + 53);
else
{
pwm02 = (127 - 53);
}

This makes the arm oscillate at the target value, and it oscillates way too much. How can we essentially LOCK the arm through programming?
  #2   Spotlight this post!  
Unread 17-02-2007, 02:47
Ben Englert Ben Englert is offline
Registered User
FRC #1072
 
Join Date: Jan 2006
Location: San Jose CA
Posts: 40
Ben Englert has a spectacular aura aboutBen Englert has a spectacular aura aboutBen Englert has a spectacular aura about
Re: Holding a position in our arm

You can't move the arm at a single hardcoded speed and then suddenly reverse it when you pass your target - you will overshoot, as I'm sure you've noticed. While full-fledged PID (PD, anyway) control would be best here, I understand you're short on time so you can implement a rudimentary version of P control like this:

You will need a PWM-limiting function that takes an integer and bounds it between 0 and 254, because otherwise the unsigned char that representes a PWM setting will roll over and you will find your motors moving backwards.

targetVal = 180;
float pGain = 0.5;
int sensor = Get_Analog_Value(foo);
pwm02 = pwm_Limit((pGain*(targetVal-sensor))+127);

And then, just tweak the pGain up or down in small increments until your arm movement is acceptable.

Again, PID feedback is great, so if you have the time to do it properly I definitely would, but you can get away with this in a pinch.
__________________
Before a match at SVR, 3/17/06
Tatsu: "Yo Englert, what's our autonomous mode?"
Me: "We'll find out, won't we."
Both: *maniacal laughter*
After the match's autonomous period ends:
Me: "Well, the basic control system still responds. That's always good."
Both: *further laughter*
  #3   Spotlight this post!  
Unread 17-02-2007, 04:02
Dave K.'s Avatar
Dave K. Dave K. is offline
Engineer/Mentor
FRC #0930
Team Role: Mentor
 
Join Date: Jan 2007
Rookie Year: 2005
Location: WI
Posts: 91
Dave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to behold
Re: Holding a position in our arm

Quote:
Originally Posted by Ben Englert View Post
You can't move the arm at a single hardcoded speed and then suddenly reverse it when you pass your target - you will overshoot, as I'm sure you've noticed. While full-fledged PID (PD, anyway) control would be best here, I understand you're short on time so you can implement a rudimentary version of P control like this:

You will need a PWM-limiting function that takes an integer and bounds it between 0 and 254, because otherwise the unsigned char that representes a PWM setting will roll over and you will find your motors moving backwards.

targetVal = 180;
float pGain = 0.5;
int sensor = Get_Analog_Value(foo);
pwm02 = pwm_Limit((pGain*(targetVal-sensor))+127);

And then, just tweak the pGain up or down in small increments until your arm movement is acceptable.

Again, PID feedback is great, so if you have the time to do it properly I definitely would, but you can get away with this in a pinch.
...this is an 8 bit microcontroller with very limited math capabilities, and floating point math is quite time consuming.

Integer math is always going to be more computationally efficient and in this case where the data source and destination have very limited precision, can be handled by simply moving the binary point up a few bits for the intermediate math, and then scale the result back down.

Here's a different way to approach the problem with a proportional only controller...

Code:
int targetVal = 180;
int sensor; 
int err;
int itmp;

#define PGAIN 5

  sensor = Get_Analog_Value(foo);
  err = targetVal - sensor;
  itmp = (PGAIN * err)/10;
  itmp = (itmp < -127)?-127:itmp;
  itmp = (itmp > 127)?127:itmp;
  pwm02 = itmp + 127;
So if PGAIN = 5 and then multiplied against the error, then divided by 10, it is the same as multiplying by 0.5.

If more resolution is needed, simply scale up the multiplers and divisors to whatever precision is desired, as long as the intermediate values will still remain within a signed 16 bit value, the math will work out fine.

If an intergal and differential term were needed then the code could be expanded like this...

Code:

int targetVal = 180;
int sensor; 
int err;
int p_out;
int i_out;
int d_out;

static int last_err = 0;
static int integrator = 0;
int delta_err;
int i_err;

int itmp;

#define PGAIN 5
#define IGAIN 3
#define DGAIN 2

  sensor = Get_Analog_Value(foo);

  err = targetVal - sensor;
  delta_err = last_err - err;
  last_err = err;
  i_err = err + integrator;

  p_out = PGAIN * err;
  i_out = IGAIN * i_err;
  d_out = DGAIN * delta_err;

  itmp = (p_out + i_out + d_out)/10;  // sum the totals and then move the binary point back into position.

  if (itmp > 127) {
      itmp = 127;
  } else if (itmp < -127) {
     itmp = -127;
  } else {
    integrator = i_err;    // limit integrator windup by only accumulating when the output values are not saturated
  }
 
  pwm02 = itmp + 127;
For the sake of example, I intentionally used different ways of accompishing the same thing in the examples and for clarity used more intermediate values than would be necessary.
__________________
--Dave
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Programming our Arm brennerator Programming 29 15-03-2007 01:17
pic: Team 498 Robot Arm Stowed Position Cactus_Robotics Robot Showcase 1 10-02-2007 21:42
PID How to hold an arm in a fixed position without a locking gear box Ian_Xodus General Forum 29 28-01-2007 08:50
Pneumatics holding their position sanddrag Pneumatics 22 15-01-2004 16:36


All times are GMT -5. The time now is 00:09.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi