Frame Scanning
Beginning with version 16.2.0, the Pinchot API offers a streamlined approach to collecting scan data known as Frame Scanning. With this update, the API now offers functions to get profiles as a sequence of frames, where each frame is an organized collection of profiles from all the scan heads in the scan system. This eliminates the need to write application code that manages individual scan heads and reassembles their returned profiles.
Basic Lineal Scan System
For a basic example, we will look at a lineal scan system with three JS-50 WX scan heads, forming a single scan zone around the log.
Each camera for each JS-50 WX is placed into its own phase, using a phase table as illustrated below:
Phase | Scan Head ID . Camera |
---|---|
1 | 1.CameraA |
2 | 2.CameraA |
3 | 3.CameraA |
4 | 1.CameraB |
5 | 2.CameraB |
6 | 3.CameraB |
Previously, it was recommended to create a thread for each scan head, each with its own scan loop. The application would then need gather all of the profiles from each thread and put them together.
With the new approach offered by Frame Scanning, only one thread is needed. This thread will manage the scan loop for all of the scan heads. The scan loop, rather than obtaining one profile at a time from an individual scan head, will read out one frame of scan data, corresponding to one complete cycle of the phase table. For this example, the frame will be ordered as follows:
Profile Index | Scan Head ID . Camera |
---|---|
1 | 1.CameraA |
2 | 1.CameraB |
3 | 2.CameraA |
4 | 2.CameraB |
5 | 3.CameraA |
6 | 3.CameraB |
The profiles for each frame will be organized in ascending order first by the scan head ID, then by the scan head's camera or laser depending on the type of JS-50 scan head and its orientation. Further details regarding profile ordering can be found below. For this example with JS-50 WX scan heads, each with the cable oriented downstream, profiles from Camera A will be placed before Camera B for a given scan head. The three scan heads will generate 6 profiles per frame; two profiles per scan head.
When scanning, frames will continue to be generated; each request to read out a frame of scan data will return one frame as formatted above. Each frame will have its own sequence number, indicating its order in time relative to other frames. This number begins at one and increments with each subsequent frame. The sequencer number is recorded in the profile data, and for a given frame, will be the same for each profile.
Carriage Headrig Example
For a more advanced example, we can consider six JS-50 X6Bs set up for a carriage headrig application. The lasers of each scan head look at its own scan zone progressing down the log.
The scan head IDs increment from left to right. The phase table is constructed in a manner as to avoid any chance of laser cross talk. Odd numbered scan heads have their lasers grouped together in the phase table; similarly, even numbered heads have their lasers grouped together in the phase table.
Phase | Scan Head ID . Laser |
---|---|
1 | 1.Laser1, 3.Laser1, 5.Laser1 |
2 | 2.Laser1, 4.Laser1, 6.Laser1 |
3 | 1.Laser2, 3.Laser2, 5.Laser2 |
4 | 2.Laser2, 4.Laser2, 6.Laser2 |
5 | 1.Laser3, 3.Laser3, 5.Laser3 |
6 | 2.Laser3, 4.Laser3, 6.Laser3 |
7 | 1.Laser4, 3.Laser4, 5.Laser4 |
8 | 2.Laser4, 4.Laser4, 6.Laser4 |
9 | 1.Laser5, 3.Laser5, 5.Laser5 |
10 | 2.Laser5, 4.Laser5, 6.Laser5 |
11 | 1.Laser6, 3.Laser6, 5.Laser6 |
12 | 2.Laser6, 4.Laser6, 6.Laser6 |
Frame scanning with JS-50 X6Bs in this example is very similar to the previous example. Given there are six scan heads with six lasers each, each frame will be composed of 36 profiles, organized first by the scan head ID, then by the laser in ascending order.
Profile Index | Scan Head ID . Laser |
---|---|
1 | 1.Laser1 |
2 | 1.Laser2 |
3 | 1.Laser3 |
4 | 1.Laser4 |
5 | 1.Laser5 |
6 | 1.Laser6 |
7 | 2.Laser1 |
8 | 2.Laser2 |
9 | 2.Laser3 |
10 | 2.Laser4 |
11 | 2.Laser5 |
12 | 2.Laser6 |
13 | 3.Laser1 |
14 | 3.Laser2 |
. . . | . . . |
29 | 5.Laser5 |
30 | 5.Laser6 |
31 | 6.Laser1 |
32 | 6.Laser2 |
33 | 6.Laser3 |
34 | 6.Laser4 |
35 | 6.Laser5 |
36 | 6.Laser6 |
Set Up
The following new functions have been added to the API to allow frame scanning:
public void StartScanning(
uint periodUs
DataFormat dataFormat
ScanningMode mode)
public void ClearFrames()
public IFrame TakeFrame(
CancellationToken token)
public bool TryTakeFrame(
out IFrame frame,
TimeSpan timeout,
CancellationToken token)
For specifics regarding any of the above functions, the API documentation should be consulted. Generally however, Frame Scanning requires the following:
- Configure the scan system and scan heads using the API as usual.
- Begin scanning, using the explicit Frame Scanning option / function.
- In the receive thread, read out frames as they become available.
- Stop scanning using the API as usual.
Notes
Profile Ordering
With frame scanning, the profiles are consistently ordered across individual frames. The profiles are first placed in ascending order according to their scan head ID. Then, the profiles are ordered by camera or laser, as shown below according to the scan head model:
- Camera: JS-50 WX
- Laser: JS-50 X6B, JS-50 Z8
Note that single camera & laser scan heads, such as the JS-50 WSC and the JS-50 MX, don't require further ordering as they can only generate one profile per frame; note the phase table constraints required for frame scanning.
The camera/laser ordering is affected by the cable orientation set for a given scan head. The orientation causes the profiles to be arranged such that the profiles from a camera/laser further downstream will be placed after those further upstream. Explicitly, this means the following order:
Cable Downstream
- JS-50 WX: Camera A, Camera B
- JS-50 X6B: Laser 6, Laser 5, Laser 4, Laser 3, Laser 2, Laser 1
- JS-50 X6B: Laser 8, Laser 7, Laser 6, Laser 5, Laser 4, Laser 3, Laser 2, Laser 1
Cable Upstream
- JS-50 WX: Camera B, Camera A
- JS-50 X6B: Laser 1, Laser 2, Laser 3, Laser 4, Laser 5, Laser 6
- JS-50 X6B: Laser 1, Laser 2, Laser 3, Laser 4, Laser 5, Laser 6, Laser 7, Laser 8
JoeScan suggests setting the scan head ID for the scan heads in a given scan system in ascending order moving down the chain. This allows the data returned by a given frame to be ordered in software in a similar manner as the scan heads are ordered physically in the mill.
Partial Frames
In normal circumstances, each frame should have one profile for each camera/laser pair for each scan head. It is possible however to receive a partial frame where one or more profiles is missing if an error is encountered. Typically this will only happen if the network has some fault or the client PC is delayed in reading out scan data. In the .NET API, an invalid profile is set to null
within the frame. In the C API, helper macros jsProfileIsValid
and jsRawProfileIsValid
are provided and return a boolean
value indicating if it is valid or not.
Thread Priority
It is recommended to increase the thread priority of the thread reading out frames. This is critically important if scanning at high speeds or if the CPU experiences higher loads. If the receive thread falls behind, partial frames will likely result, causing problems further in the application. Placing the thread at the highest level, either ThreadPriority.Highest
for .NET or THREAD_PRIORITY_TIME_CRITICAL
for C/C++, will ensure that the thread is serviced and frames are read out as they become available.
Phase Table Constraints
With Frame Scanning, it is required that the phase table only schedules a given camera/laser pair of a scan head no more than once. This is an internal implementation constraint; the API will return an error if attempting to perform frame scanning with an invalid phase table. Please reach out to a JoeScan representative if your application is affected by this limitation.