Inverting function that includes modulus

  • Context: Graduate 
  • Thread starter Thread starter cepheid
  • Start date Start date
  • Tags Tags
    Function Modulus
Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
33 replies · 7K views
cepheid said:
That could very well be it, because it is acting as though the first term on the right hand side of:

phi = (enc - enc_ref)/CNTS_PER_DEG + phi_ref

is evaluating to zero, and hence it thinks the current angle is always phi_ref. Perhaps that could be due to some order of operations problem. I will try that and report back!

I am reporting back to say that this fix worked. In hindsight it is obvious that what I entered before was resulting in first dividing by 72,000, and then dividing by 360. Not the intended effect at all.

Okkaaay, as for the rest of this discussion, although I am not interested in delving as deep into the vagaries of C as you guys are, I would like to know one thing: why are constants preferred to defines in this situation?

Finally, I have another question along similar lines. I need to do this again for my device's other axis of rotation (call this angle theta if you like, and call the encoder position y). Now, theta is physically restricted to lie between -10 deg and +89 deg (and I am required to use this coordinate system, since the zero point needs to be with reference to something external, namely the horizon). A range of 99 degrees corresponds to a range in encoder values of only 19,800 counts.

After some trial and error, I decided that there were three (mutually exclusive) possibilities, depending on the values of y0 and theta0 (neither of which are under my control, but depend on the system orientation and stored position at startup):

1. the encoder values would be monotonic throughout the range of motion

2. the encoder reference position y0 would be large enough and/or the reference angle theta0 would be far enough from the maximum angle that as you increased the angle, you'd eventually exceed 71,999, and wrap back around. This would cause the highest angles to evaluate to large and negative values, requiring addition of 360 degrees to them.

3. the encoder reference position y0 would be small enough and/or the reference angle theta0 would be far enough from the minimum angle that as you decreased the angle, you'd eventually go below 0, and wrap back around. This would cause the lowest angles to evaluate to large positive values, requiring subtraction by 360.

Based on these scenarios, I concluded that I could just use the same equation as before:

[tex]\theta(y) = \left[ (y-y_0)\left(\frac{360^\circ}{72,000}\right) + \theta_0 \right]~\textrm{mod}~360^\circ[/tex]

Using this formula:

- the positive angles (those between 0 and 89) would always turn out right

- the negative angles would have 360 added to them, and this would have to be "undone." Since the formula would produce large positive values (between 350 and 359 -- much larger than the maximum angle) for the negative angles, I added a line that said if (theta > 89.0) theta -= 360.0;

Does anyone see any errors?
 
Last edited:
Mathematics news on Phys.org
cepheid said:
I am reporting back to say that this fix worked. In hindsight it is obvious that what I entered before was resulting in first dividing by 72,000, and then dividing by 360. Not the intended effect at all.

Nice! :smile:

cepheid said:
Okkaaay, as for the rest of this discussion, although I am not interested in delving as deep into the vagaries of C as you guys are, I would like to know one thing: why are constants preferred to defines in this situation?

Yeah, sorry we hijacked your thread. I hope you don't mind! :wink:

As you have seen, macro's are tricky.
It's very easy for them to behave other than you expect.
What you found is just one of the many pitfalls.

In particular with constants you need to specify the type, which means additional checks are made by the compiler that everything is in order.
This is called "type safety".


cepheid said:
Finally, I have another question along similar lines.
...
Does anyone see any errors?

I don't quite understand what you are doing (your text is too long ;)).
If I understand correctly you want to map a range of encoder values to a range of angle values.
What are those ranges exactly?
And why do you think there might be a problem?
 
cepheid said:
I am reporting back to say that this fix worked. In hindsight it is obvious that what I entered before was resulting in first dividing by 72,000, and then dividing by 360. Not the intended effect at all.

Those silly #define-induced logic errors always are obvious in hindsight ...

Okkaaay, as for the rest of this discussion, although I am not interested in delving as deep into the vagaries of C as you guys are, I would like to know one thing: why are constants preferred to defines in this situation?

As was already pointed out, type safety is one reason ... the other is what you already experienced ... the macro-preprocessor has one job .. to go through and do text-based find-and-replace of your macros throughout your code. Therefore, it is much less context sensitive than the compiler, and is prone to face-palm-worthy goof ups like the one you experienced.

Finally, I have another question along similar lines. I need to do this again for my device's other axis of rotation (call this angle theta if you like, and call the encoder position y). Now, theta is physically restricted to lie between -10 deg and +89 deg (and I am required to use this coordinate system, since the zero point needs to be with reference to something external, namely the horizon). A range of 99 degrees corresponds to a range in encoder values of only 19,800 counts.

... depending on the values of y0 and theta0 (neither of which are under my control, but depend on the system orientation and stored position at startup)

Before answering, I need to know whether or not y0 and theta0 are truly independent, or if they are correlated ... actually this question holds for x0 and phi0 as well.In other words, when you start up, if you run the value of x0 through your formula, do you get phi0, and vice-versa? Or are the encoder and the "true" angle values unrelated at startup?

The reason I ask is that the formula I came up with before assumes that they are uncorrelated. It should be possible to use a much simpler formula if the values are correlated.

A similar question has to do with the encoder ... is it a physical entity, or is it just a theoretical construct to help you control your device (telescope?) with a computer?
 
SpectraCat said:
Before answering, I need to know whether or not y0 and theta0 are truly independent, or if they are correlated ... actually this question holds for x0 and phi0 as well.In other words, when you start up, if you run the value of x0 through your formula, do you get phi0, and vice-versa? Or are the encoder and the "true" angle values unrelated at startup?

Phi0 and x0 are independent. Same for y0 and theta0. At the startup of my program, I have to enter the reference angles. I can choose whatever phi0 I want, because I can choose whatever coordinate system I want for that direction (azimuth). In contrast, I have to measure the starting theta0 relative to a fixed coordinate system (for elevation) and enter it in. The encoder positions x0 and y0 at startup are outside of my control, because the last known positions are "remembered" by the readout electronics from previous runs of the program (unless if I power cycle everything). So I don't get to choose which values of x0 and y0 map to my chosen/measured phi0 and theta0.

SpectraCat said:
The reason I ask is that the formula I came up with before assumes that they are uncorrelated. It should be possible to use a much simpler formula if the values are correlated.

I'm pretty happy with the formula I stated in post #31. It seems to hold up under testing so far. In fact, I'm convinced that if the reasoning that I outlined in those three enumerated points in that post is correct, then the formula (with the correction for negative angles) is also correct. So it was mostly just that reasoning on which I wanted feedback.

SpectraCat said:
A similar question has to do with the encoder ... is it a physical entity, or is it just a theoretical construct to help you control your device (telescope?) with a computer?

The encoders are real devices. As I stated before, they are incremental encoders with a resolution of 72,000 counts per revolution. And yes, my device is a scanning mount for a cryostat that houses a microwave telescope.