A Simple Object-Space Telecentric System
Object-space telecentricity
I have been working on a software package recently for optical systems design. The process of building the package has proceeded like this:
- Think of a particular case that I want to model; for example an infinite conjugate afocal system
- Implement it in the code
- Discover that the code doesn't work
- Create a test case that helps debug the code
- Repeat
I am modeling a telecentric lens in the current iteration of this loop. To keep things simple, I am limiting myself to an object-space telecentric system. This was more challenging than I expected. In part, the reason is that I was trying to infer whether a system was or was not telecentric from the lens prescription data and a ray trace, which has two problems:
- I need to do a floating point comparison between two numbers to say whether a system is telecentric. Either the chief ray angle in object-space has to be zero or the entrance pupil must be located at infinity. Floating point comparisons are notoriously difficult to get right, and if you're doing them then you might want to rethink what you're trying to model.
- Numerous checks are needed before we can even trace any rays. For example, I should check first whether the user placed the object at infinity. This would form the image in the same plane as the aperture stop, which does not really make sense.
I find it interesting that Zemax addresses these problems by introducing object-space telecentricity as an extra boolean flag that forces the chief ray angle to be zero in the object-space. In other words, the user needs to know what they're doing and to specify that they want telecentricity from the beginning.
An object-space telecentric example
I adapted the following example from lens data presented in this video: https://www.youtube.com/watch?v=JfstTsuNAz0. Notably, the object distance was increased by nearly a factor of two from what was given in the video so that the image plane was at a finite distance from the lens. Paraxial ray trace results were computed by hand.
Surface | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
Comment | OBJ | STOP | IMG | ||
\( R \) | \( \infty \) | -9.750 | |||
\( t \) | 29.4702 | 2 | 15.97699 | 17.323380 | |
\( n \) | 1 | 1.610248 | 1 | 1 | |
\( C \) | 0 | -0.10256 | |||
\( -\Phi \) | 0 | -0.06259 | |||
\( t/n \) | 29.4702 | 1.24204 | 15.97699 | 17.323380 | |
\( y \) | 0 | 29.4702 | 30.712240 | 15.97699 | 0 |
\( nu \) | 1 | 1 | -0.922279 | -0.922279 | |
\( \bar{y} \) | 1 | 1 | 1 | 0 | -1.084270 |
\( n \bar{u} \) | 0 | 0 | -0.06259 | -0.06259 |
This system is shown below with lens semi-diameters of 5 mm. Note that the stop is at the paraxial focus of the lens. The rays in the sketch cross the axis before the stop because of spherical aberration.
Remarks
Marginal ray trace
At first the marginal ray trace was a bit confusing because the entrance pupil is at infinity. How can the marginal ray, which intersects the pupil at its edge, be traced when the pupil is at infinity? Then I remembered that I don't aim for the edge of the pupil when tracing the marginal ray. Instead, I launch a ray from the axis in the object plane at a random angle taking the surface with the smallest ray height as the aperture stop. (I chose a paraxial angle of 1 in the table above. Technically, this is called a pseudo-marginal ray. The real marginal ray is calculated from it by rescaling the surface intersection heights by the aperture stop semi-diameter.) Once you have the marginal ray in image space, just find its intersection with the axis to determine the image location.
Telecentric lens design
So how would an object-space telecentric design be implemented in software? First, I'd set an option that would force the chief ray angle to 0 in the object space. Then, I'd simply place a solve on the aperture stop that puts it at the location where the chief ray intersects the axis.