Special:
|
[DAT] (requires LDraw-compatible viewer)
|
Subject:
|
finally! the whole fix! (was: more on the rotation sensor)
|
Newsgroups:
|
lugnet.robotics.rcx.legos
|
Date:
|
Sun, 30 Jan 2000 02:29:27 GMT
|
Viewed:
|
2676 times
|
| |
| |
In lugnet.robotics.rcx.legos, Ben Jackson writes:
>
> For example:
>
> actual: 0 -> 1 -> 2 -> 3
> samples: 0003111122222333333
I *finally* figured out why none of my attempts to fix this in the state
machine were working. If you consider forward and backward motion:
0 1 2 3 0
031 213 0
3 2 1 0 3
312 130 3
The first line indicates the actual sensor transitions. The second line
indicates all of the actual and possible transient sensor values. While
working on a state machine that would take all of those into account, I finally
noticed: both of them are the same: 3,1,2,1,3,0. So there is no way for a
state machine alone to figure out what to do about the extra '1' states which
pop up in the state stream.
So as Philip Brown suggested, the sensors need to be debounced. I did some
tests and proved that the transient states only appear for one A/D cycle, so I
changed the sensor code to ignore any A/D reading which only lasts for one
cycle. The result is a kernel which appears to track the rotation sensor 100%
correctly! This works with no errors to over 1000RPM (I haven't worked out
exactly how fast it can go) which is the limit of the ability of the RCX to
interpret the rotation sensor inputs.
So without further ado, here's the unidiff to kernel/dsensor.c from v0.2.3
(beware line wraps, ask me to email if you can't get it to work):
--- orig/legOS/kernel/dsensor.c Wed Nov 17 10:25:27 1999
+++ fixed/legOS/kernel/dsensor.c Sat Jan 29 18:25:12 2000
@@ -62,6 +62,8 @@
volatile int ds_rotations[3]; //!< sensor revolutions * 16
static signed char rotation_state[3]; //!< rotation state
+static signed char rotation_new_state[3]; //!< proposed rotation state
+static unsigned int state_duration[3]; //!< proposed rotation state
duration
//! convert a/d values to rotation states
/*! Indexed with (value>>12).
@@ -69,7 +71,7 @@
*/
static const signed char ad2state[16]={
// 0 1 2 3 4 5 6 7 8 9 a b c d e f // (sensor value>>12)
- -1,-1,-1,-1,-1,-1, 2, 2,-1, 3, 3,-1, 1, 1,-1, 0
+ -1,-1,-1,-1,-1,-1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 0
};
//! convert state difference to revolution count change
@@ -104,6 +106,8 @@
state=0;
rotation_state[channel]=state;
+ rotation_new_state[channel] = -1;
+ state_duration[channel]=0;
ds_rotations[channel]=pos; // reset counter
}
}
@@ -116,13 +120,21 @@
unsigned channel =ds_channel;
unsigned raw =(*((&AD_A)+channel));
signed char newstate=ad2state[raw>>12];
-
- if(newstate>=0) {
- signed char diff=newstate-rotation_state[channel];
- if(diff) {
- ds_rotations[channel]+=diff2change[diff+3];
- rotation_state[channel]=newstate;
+
+ if (newstate < 0)
+ return;
+
+ if (newstate == rotation_new_state[channel]) {
+ if (++state_duration[channel] == 2) {
+ signed char diff = newstate - rotation_state[channel];
+
+ ds_rotations[channel] += diff2change[diff+3];
+ rotation_state[channel] = newstate;
+ rotation_new_state[channel] = -1;
}
+ } else if (newstate != rotation_state[channel]) {
+ rotation_new_state[channel] = newstate;
+ state_duration[channel] = 1;
}
}
#endif // CONF_DSENSOR_ROTATION
|
|
Message is in Reply To:
| | Re: more on the rotation sensor
|
| (...) value) (...) The order is numerical, either 0->1->2->3->0... or 0->3->2->1->0... That's why legOS has them enumerated that way. The Mindstorms fw numbers them differently, which is why I mentioned it. (...) I don't think your specific example (...) (25 years ago, 29-Jan-00, to lugnet.robotics.rcx.legos)
|
3 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|