From a21a413cada47a5167416eb18ef176535d36a1ec Mon Sep 17 00:00:00 2001 From: watts Date: Wed, 22 Nov 2023 11:49:30 +0100 Subject: [PATCH] Update Orocos Configuration --- Orocos-Configuration.md | 228 ++++++++++++++++++++-------------------- 1 file changed, 113 insertions(+), 115 deletions(-) diff --git a/Orocos-Configuration.md b/Orocos-Configuration.md index a11b651..300c837 100644 --- a/Orocos-Configuration.md +++ b/Orocos-Configuration.md @@ -1,15 +1,121 @@ Orocos needs to be configured to your hardware, this involves: -1. Loading the correct kernel modules for hardware drivers -2. Identifying (or verifying) the device numbers that Comedi is assigning to each card -3. Set the correct device numbers in the Orocos start.ops file -4. Load and use the correct hardware drivers in the Orocos start.ops file +1. Identifying (or verifying) the device numbers that Comedi is assigning to each card +2. Set the correct device numbers in the Orocos start.ops file +3. Load and use the correct hardware drivers in the Orocos start.ops file -## Kernel Driver Modules +## Identify Device Numbers -The correct module names for your hardware can be found on the [Comedi website](https://www.comedi.org/hardware.html). Searching for just the number part of the card name is a quick way to find it. +The device numbers assigned to each card can be found in the kernel message log, which is printed with `dmesg` (might need `sudo dmesg`). There can be a lot of messages to sort through, so you can narrow it down with `dmesg | grep comedi`. This should produce output that includes lines like (example from PolLux): + +``` +[ 2.507480] comedi4: ni_660x: +[ 2.507890] comedi: cannot get unshared interrupt, will not use RT interrupts. +[ 2.511676] comedi1: ni_pcimio: +[ 2.544959] comedi2: ni_pcimio: +[ 2.546311] comedi: cannot get unshared interrupt, will not use RT interrupts. +[ 2.547515] comedi2: ni_pcimio: possible problem - never saw adc go busy? +[ 2.698319] comedi3: n1231: +[ 2.698331] comedi3: found n1231a at PCI bus 3, slot 0 +[ 2.698525] comedi3: N1231 now attached. +[ 2.699254] comedi0: ni_660x: +``` +We are looking for messages in the format of `comedi4: ni_660x:`, which tells us that an NI6602 card (with `ni_660x` kernel module) has been assigned the device number `4` by Comedi. Further information can often be found in the lines in between those containing "comedi" and you can use the timestamp on the left to quickly find the appropriate section of the message log. Some other useful commands for identifying hardware include: +- `lspci` +- `comedi_board_info /dev/comedi0` (try with each device found with `ls /dev/comedi?`) + +This corresponds to a PolLux configuration with: +- NI-6602 (ni_660x) assigned device number 0 +- NI-6289 (ni_pcimio) assigned device number 1 +- NI-6733 (ni_pcimio) assigned device number 2 +- Agilent N1231 (n1231a) assigned device number 3 +- NI-6602 (ni_660x; used for reading the output of the Attocube interferometer) assigned device number 4 + +If you have multiple cards using the same driver, then it can be a bit complicated to figure out which is which. As a rule, Comedi will tend to assign a smaller device number to the card with the higher PCI address. + +## Setting Device Numbers In start.ops + +The device numbers must be assigned correctly in the `start.ops` file used to configure Orocos. The first section of the `start.ops` file for PolLux looks like: + +``` +// deployer-gnulinux -s start.ops -linfo + +import("SensorAgilentPCI") +import("SensorAttocube") +import("PIDLoop") +import("ComController") +import("zmqStreamer") +import("AnalogOutputComedi") +import("DigitalOutputComedi") +import("TrajectoryGenerator") +import("PositionSampler") +import("RealtimeSampler") +import("DigitalInputComedi") + + +loadComponent("Sensor1","SensorAgilentPCI") +loadComponent("Sensor2","SensorAttocube") +loadComponent("PID0","PIDLoop") +loadComponent("PID1","PIDLoop") +loadComponent("PID2","PIDLoop") +loadComponent("ComCon", "ComController") +loadComponent("zmqStream0", "ZmqStreamer") +loadComponent("AO1", "AnalogOutputComedi") +loadComponent("DO1", "DigitalOutputComedi") +loadComponent("TrajGen","TrajectoryGenerator") +loadComponent("PosSampler","PositionSampler") +loadComponent("RtSampler","RealtimeSampler") +loadComponent("DI1", "DigitalInputComedi") +``` + +Take note of each `loadComponent` command where the imported object (second argument) has "Sensor", "Input" or "Output" in the name. Each of these will need to be assigned a device number, using the name given in the first argument of the command. + +In this case, we should declare the following assignments: +``` +Sensor1.deviceNr=3 +Sensor2.deviceNr=4 +AO1.deviceNr=2 +DO1.deviceNr=2 +DI1.deviceNr=2 +``` +These assignments must be declared after the corresponding device names are defined with `loadComponent` and after they are configured with a command like `Sensor1.configure()`. + +**WARNING** : There are currently some inconsistencies in the device number variable names and whether the "configure" and "start" functions use parentheses. The plan is to standardise on "deviceNr" and "configure()" + +| Device Type | Variable Name | Function Syntax | +| ------ | ------ | ------ | +| SensorAgilentPCI | device_nr | configure; start | +| SensorAttocube | device_nr | configure; start | +| AnalogOutputComedi | device_nr | configure(); start() | +| DigitalOutputComedi | device_nr | configure(); start() | +| DigitalInputComedi | deviceNr | configure; start | + +## Configuring start.ops + +The `start.ops` file tells Orocos how to define devices and how signals are interconnected. Note that the feedback loops are "PID0" for the X-axis, "PID1" for the Y-axis and "PID2" for the Z-axis. + +It is probably best to start with the file configured for PolLux ([PixelatorRealtime/startup/PolLux/start.ops](https://gitlab.psi.ch/microspectro/pixelator/-/blob/master/PixelatorRealtime/startup/PolLux/start.ops)) and adapting to your instrument. There are three things that might make PolLux different from your system: +1. The device numbers. +2. The interferometer module(s). +3. The number of interferometer axes being used. + +### Device Numbers +Currently, the device numbers at PolLux match the hard-coded defaults and so no device numbers are set. The section above discusses how to set the appropriate device numbers in `start.ops`. + +### Interferometer Module(s) and Axes +An interferometer module is first imported (`import()`) and then loaded and assigned a name (`loadComponent()`). PolLux uses an Agilent interferometer for the X- and Y-axes, and an Attocube interferometer for the Z-axis. You should only import the module(s) that you need for the interferometer type(s) used in your instrument. If you only have one interferometer type, then you should delete one of the `import()` commands and one of the 'loadComponent()` commands so that the remaining commands refer to the interferometer module that you want to use. Further, ensure that the `loadComponent()` command uses the name (first argument) "Sensor1". Next, you will need to modify or delete a bunch of commands, depending on whether you have a Z-axis interferometer. + +### Two Interferometer Axes (of same type) +If you have only X- and Y-axis interferometers, you can delete all commands (the full line) that include either "Sensor2" or "PID2" (or both). + +### Three Interferometer Axes (of same type) +If you have X-, Y- and Z-axis interferometers, you should first look at every `connect()` command and change any instance of "Sensor2.*Output_0" (where * is either "position" or "status") in that command to "Sensor1.*Output_2". After doing this throughout the file, you should delete any command (the full line) that still contains "Sensor2". + + +## Manual Loading of Kernel Driver Modules (optional) + +Comedi is now part of the Linux kernel and it can automatically load the correct modules for the hardware present. If you have problems then you could set up manual loading of a specific set of kernel modules. The correct module names for your hardware can be found on the [Comedi website](https://www.comedi.org/hardware.html). Searching for just the number part of the card name is a quick way to find it. -Comedi is now part of the Linux kernel and it can automatically load the correct modules for most hardware. If you have problems then you can set up manual loading of a specific set of kernel modules. Manual loading of kernel modules is done in two steps: 1. Turning off automatic loading: @@ -79,111 +185,3 @@ The next command `/usr/local/sbin/comedi_config /dev/comedi1 ni_pcimio` will sta The next command `/usr/local/sbin/comedi_config /dev/comedi2 ni_pcimio` will look past address "03:04.0" (wrong module) and "03:03.0" (already assigned), and then assign `/dev/comedi2` to the NI-6733 card in PCI address "03:02.0". The next two commands assign `/dev/comedi3` to the Agilent N1231A card in PCI address "03:00.0", and then assign `/dev/comedi0` to the NI-6602 card in PCI address "03:01.0" - -## Identify/Verify Device Numbers - -The device numbers assigned to each card can be found in the kernel message log, which is printed with `dmesg` (might need `sudo dmesg`). There can be a lot of messages to sort through, so you can narrow it down with `dmesg | grep comedi`. This should produce output that includes lines like (example from PolLux): - -``` -[ 2.507480] comedi4: ni_660x: -[ 2.507890] comedi: cannot get unshared interrupt, will not use RT interrupts. -[ 2.511676] comedi1: ni_pcimio: -[ 2.544959] comedi2: ni_pcimio: -[ 2.546311] comedi: cannot get unshared interrupt, will not use RT interrupts. -[ 2.547515] comedi2: ni_pcimio: possible problem - never saw adc go busy? -[ 2.698319] comedi3: n1231: -[ 2.698331] comedi3: found n1231a at PCI bus 3, slot 0 -[ 2.698525] comedi3: N1231 now attached. -[ 2.699254] comedi0: ni_660x: -``` -We are looking for messages in the format of `comedi4: ni_660x:`, which tells us that an NI6602 card (with `ni_660x` kernel module) has been assigned the device number `4` by Comedi. Further information can often be found in the lines in between those containing "comedi" and you can use the timestamp on the left to quickly find the appropriate section of the message log. Some other useful command for identifying hardware include: -- `lspci` -- `comedi_board_info /dev/comedi0` (try with each device found with `ls /dev/comedi?`) - -This corresponds to a PolLux configuration with: -- NI-6602 (ni_660x) assigned device number 0 -- NI-6289 (ni_pcimio) assigned device number 1 -- NI-6733 (ni_pcimio) assigned device number 2 -- Agilent N1231 (n1231a) assigned device number 3 -- NI-6602 (ni_660x; used for reading the output of the Attocube interferometer) assigned device number 4 - -If you have multiple cards using the same driver, then it can be a bit complicated to figure out which is which. As a rule, Comedi will tend to assign a smaller device number to the card with the higher PCI address. - -## Setting Device Numbers In start.ops - -The device numbers must be assigned correctly in the `start.ops` file used to configure Orocos. The first section of the `start.ops` file for PolLux looks like: - -``` -// deployer-gnulinux -s start.ops -linfo - -import("SensorAgilent") -import("SensorAttocube") -import("PIDLoop") -import("ComController") -import("zmqStreamer") -import("AnalogOutputComedi") -import("DigitalOutputComedi") -import("TrajectoryGenerator") -import("PositionSampler") -import("RealtimeSampler") -import("DigitalInputComedi") - - -loadComponent("Sensor1","SensorAgilent") -loadComponent("Sensor2","SensorAttocube") -loadComponent("PID0","PIDLoop") -loadComponent("PID1","PIDLoop") -loadComponent("PID2","PIDLoop") -loadComponent("ComCon", "ComController") -loadComponent("zmqStream0", "ZmqStreamer") -loadComponent("AO1", "AnalogOutputComedi") -loadComponent("DO1", "DigitalOutputComedi") -loadComponent("TrajGen","TrajectoryGenerator") -loadComponent("PosSampler","PositionSampler") -loadComponent("RtSampler","RealtimeSampler") -loadComponent("DI1", "DigitalInputComedi") -``` - -Take note of each `loadComponent` command where the imported object (second argument) has "Sensor", "Input" or "Output" in the name. Each of these will need to be assigned a device number, using the name given in the first argument of the command. - -In this case, we should declare the following assignments: -``` -Sensor1.deviceNr=3 -Sensor2.deviceNr=4 -AO1.deviceNr=2 -DO1.deviceNr=2 -DI1.deviceNr=2 -``` -These assignments must be declared after the corresponding device names are defined with `loadComponent` and after they are configured with a command like `Sensor1.configure()`. - -**WARNING** : There are currently some inconsistencies in the device number variable names and whether the "configure" and "start" functions use parentheses. The plan is to standardise on "deviceNr" and "configure()" - -| Device Type | Variable Name | Function Syntax | -| ------ | ------ | ------ | -| SensorAgilent | device_nr | configure; start | -| SensorAttocube | device_nr | configure; start | -| AnalogOutputComedi | device_nr | configure(); start() | -| DigitalOutputComedi | device_nr | configure(); start() | -| DigitalInputComedi | deviceNr | configure; start | - -## Configuring start.ops - -The `start.ops` file tells Orocos how to define devices and how signals are interconnected. Note that the feedback loops are "PID0" for the X-axis, "PID1" for the Y-axis and "PID2" for the Z-axis. - -It is probably best to start with the file configured for PolLux ([PixelatorRealtime/startup/PolLux/start.ops](https://gitlab.psi.ch/microspectro/pixelator/-/blob/master/PixelatorRealtime/startup/PolLux/start.ops)) and adapting to your instrument. There are three things that might make PolLux different from your system: -1. The device numbers. -2. The interferometer module(s). -3. The number of interferometer axes being used. - -### Device Numbers -Currently, the device numbers at PolLux match the hard-coded defaults and so no device numbers are set. The section above discusses how to set the appropriate device numbers in `start.ops`. - -### Interferometer Module(s) and Axes -An interferometer module is first imported (`import()`) and then loaded and assigned a name (`loadComponent()`). PolLux uses an Agilent interferometer for the X- and Y-axes, and an Attocube interferometer for the Z-axis. You should only import the module(s) that you need for the interferometer type(s) used in your instrument. If you only have one interferometer type, then you should delete one of the `import()` commands and one of the 'loadComponent()` commands so that the remaining commands refer to the interferometer module that you want to use. Further, ensure that the `loadComponent()` command uses the name (first argument) "Sensor1". Next, you will need to modify or delete a bunch of commands, depending on whether you have a Z-axis interferometer. - -### Two Interferometer Axes (of same type) -If you have only X- and Y-axis interferometers, you can delete all commands (the full line) that include either "Sensor2" or "PID2" (or both). - -### Three Interferometer Axes (of same type) -If you have X-, Y- and Z-axis interferometers, you should first look at every `connect()` command and change any instance of "Sensor2.*Output_0" (where * is either "position" or "status") in that command to "Sensor1.*Output_2". After doing this throughout the file, you should delete any command (the full line) that still contains "Sensor2". -