latest version v1.9 - last update 10 Apr 2010 |
This class performs handling of the pan-tilt unit PTU-D46-17 from the manufactor DirectedPerception. More...
#include <ltiDirectedPerceptionPTU.h>
Classes | |
class | parameters |
The parameters for the class DirectedPerceptionPTU. More... | |
Public Member Functions | |
directedPerceptionPTU () | |
directedPerceptionPTU (const parameters &par) | |
directedPerceptionPTU (const directedPerceptionPTU &other) | |
virtual | ~directedPerceptionPTU () |
virtual const char * | getTypeName () const |
directedPerceptionPTU & | copy (const directedPerceptionPTU &other) |
directedPerceptionPTU & | operator= (const directedPerceptionPTU &other) |
virtual functor * | clone () const |
const parameters & | getParameters () const |
bool | initialize () |
bool | setAngleFormat (parameters::eAngleFormatType anAngleFormat) |
bool | setExecMode (parameters::eExecModes anExecMode) |
bool | setPosMode (parameters::ePosModes anPosMode) |
bool | reset () |
bool | stopPanTilt () |
bool | stopPan () |
bool | setPanTilt (float pan, float tilt) |
bool | setPan (float pan) |
bool | setTilt (float tilt) |
bool | getPanTilt (float &pan, float &tilt) const |
float | getPan () const |
float | getTilt () const |
bool | getCurrentPanTilt (float &pan, float &tilt) |
float | getCurrentPan () |
float | getCurrentTilt () |
bool | setAutoscan (float panPos1, float panPos2) |
bool | setAutoscan (float panPos1, float panPos2, float tiltPos1, float tiltPos2) |
bool | setAutoscan () |
bool | stopAutoscan () |
bool | setPanSpeed (float panSpeed) |
bool | setTiltSpeed (float tiltSpeed) |
float | getMaxPanSpeed () |
float | getMinPanSpeed () |
float | getMaxTiltSpeed () |
float | getMinTiltSpeed () |
bool | setPanAcceleration (float panAcc) |
bool | setTiltAcceleration (float tiltAcc) |
float | getMaxPanAcceleration () |
float | getMinPanAcceleration () |
float | getMaxTiltAcceleration () |
float | getMinTiltAcceleration () |
bool | isPTUidle () |
bool | awaitPosCommandCompletion () |
bool | updatePanTilt () |
Protected Member Functions | |
parameters & | getWritableParameters () |
int | convertValueToPTUnits (float position) |
void | emptySerialBuffer () |
This class performs handling of the pan-tilt unit PTU-D46-17 from the manufactor DirectedPerception.
Base data (taken from the specifications) | ||
Pan range | -159 degrees | +159 degrees |
Tilt Range | -47 degrees | +31 degrees |
Max unloaded speed | 300 degrees/second | |
Resolution | 3.086' = 0.051428 degrees/position |
Initializing
Before you start sending any commands, the pan-tilt unit (PTU) has to be initialized. This happens by using directedPerceptionPTU::initialize(). If this method has not been successfully executed, all methods working on the PTU will not do and return a false with an adequate report in the status string. The routine tests the communication between the serial port and the PTU, sets pan/tilt position to 0,0, acceleration and speed to default values. They should deal with the most mounted loads.
Execution modes
As you can see from the corresponding methods, the pan-tilt unit provides two execution functions: slaved and immidiate. The standard mode is immidiate. In immidiate mode, position commands are excuted at once, when they have been sent to the unit. In slaved mode, position commands are not executed before an await command was send. That means in fact not before directedPerceptionPTU::awaitPosCommandCompletion() is applied. This realizes that pan and tilt movement act more or less synchronously. An adequate example in angle format degrees might be:
lti::directedPerceptionPTU ptu; ptu.setExecMode(directedPerceptionPTU::parameters::slaved); ptu.setPan(-90.f); ptu.setTilt(30.f); ptu.awaitPosCommandCompletion();
If you give more than one pan and tilt combination only the last one will be applied, because the earlier ones are overwritten immediately.
Speeds and Accelerations
Note that minimum/maximum pan and tilt speeds/accelerations are more less experimental. So some speed and acceleration combinations could not be legal. As in speed and acceleration setting it is not checked, whether the pan-tilt unit took over the changes correctly, it could happen, that a setting function returns true, although the PTU rejected the given values. If you have the feeling that some settings were not applied, try values, which have a larger distance to the max. or min. borders. In most cases this will not occur, since it is not necessary to set extreme speed and acceleration values for common applications. Also the max/min speeds and accelerations are already limited.
If you like to experiment with the pan-tilt unit to test it, use a terminal programm (e.g. minicom under linux) to set up communication between the pc and the device. Work with 9600 baud, 1 start bit, 8 data bits, 1 stop bit, no parity. The instructions can be taken from the manual which you can find under www.directedPerception.com
Relative positions
As announced in some methods, relative positioning provides the danger of huge divergences between the real and the internal positions. This can occur, if a big amount of relative position commands are set after each other very fast, without a sufficent break between them. Then the internal positions are faster updated, than the the pan-tilt could execute the commands. What happens, is the following: E.g. the PTU gets the command to pan relatively with a few degrees. Before that is finished, the next command arrives and tells to pan again relatively with some degrees. Now the position of the new command does not calculate from where the first would end in a few seconds, but from where it is currently located. Thus, errors accumulate over time. That results in an decreasing driving interval . This could be avoided, if a long enoug sleep command is applied between position setting or working with the await and isIdle methods as shown in the example. If a not wanted difference has been recognized the internal values could be updated with the real ones by using directedPerceptionPTU::updatePanTilt(). Be aware that the values can only be updated, if directedPerceptionPTU::isPTUidle() returns true. Otherwise the positions can not be read from the unit.
Determining an idle pan-tilt unit
The method directedPerceptionPTU::isPTUidle() provides to check the PTU working condition. Each time, when a method is called, which directly sends commands to the pan-tilt unit, an instruction counter is increased. For every command which is successfully applied the unit sends an asterix '*' and for each failed command a '!'. The method reads out the serial buffer and decreases the instruction counter with the number of '*' and '!' it has read. So, if all commands have been worked out, the instruction counter is back to zero and the method returns true. Otherwise, if the instruction counters value is greater than zero, it returns false.
Note that in immidiate execution mode an asterix is already returned from the pan-tilt unit, if the desired position can be driven, but has not started moving yet. That means, that directedPerceptionPTU::isPTUidle() returns also true, if the last position command is still being executed. You can avoid this by subsequently calling directedPerceptionPTU::awaitPosCommandCompletion(). Then the idle method only returns true, when the pan-tilt unit has finished its move.
Here is a short example code for using the pan-tilt unit.
#include "ltiDirectedPerceptionPTU.h" #include <iostream> int main(void) { lti::directedPerceptionPTU ptu; ptu.initialize(); // Test the connection and make first settings ptu.setAngleFormat(lti::panTiltUnit::parameters::Degrees); // Set angle format to degrees ptu.setPan(90.f); // Set Pan to 90 ptu.awaitPosCommandCompletion(); // Do not accept commands till ptu is in position while ( !ptu.isPTuIdle() ) { // Wait until position is reached // do nothing } cout << "Internal position: " << ptu.getPan() << endl; cout << "Real position: " << ptu.getCurrentPan() << endl; // Now this will cause a huge difference between real and internal position // Try to drive back to zero position in 5 degrees steps and relative positioning. ptu.setPosMode(lti::directedPerceptionPTU::parameters::relative); for ( int i=0; i<90; i=i+5 ) { ptu.setPan(-i); } ptu.awaitPosCommandCompletion(); // Do not accept commands till ptu is in position while ( !ptu.isPTuIdle() ) { // Wait until position is reached // do nothing } // Print positions cout << "Internal position: " << ptu.getPan() << endl; cout << "Real position: " << ptu.getCurrentPan() << endl; cout << "Difference : " << ptu.getCurrentPan()-ptu.getPan() << " " << endl; ptu.updatePanTilt(); // Update internal parameters cout << "Updated parameters:" << endl; cout << "Internal position: " << ptu.getPan() << endl; cout << "Real position: " << ptu.getCurrentPan() << endl; cout << "Difference : " << ptu.getCurrentPan()-ptu.getPan() << " " << endl; // Drive to starting position ptu.setPosMode(lti::directedPerceptionPTU::parameters::relative); ptu.setPan(0.f); return(0); }
lti::directedPerceptionPTU::directedPerceptionPTU | ( | ) |
Default constructor.
lti::directedPerceptionPTU::directedPerceptionPTU | ( | const parameters & | par | ) |
Construct a functor using the given parameters.
lti::directedPerceptionPTU::directedPerceptionPTU | ( | const directedPerceptionPTU & | other | ) |
Copy constructor.
other | the object to be copied |
virtual lti::directedPerceptionPTU::~directedPerceptionPTU | ( | ) | [virtual] |
Destructor.
bool lti::directedPerceptionPTU::awaitPosCommandCompletion | ( | ) |
Await the last position command to be completed.
The pan-tilt unit is instructed to wait executing further commands until the last position command is completed. This means till the given pan and tilt positions are physically reached.
virtual functor* lti::directedPerceptionPTU::clone | ( | ) | const [virtual] |
Returns a pointer to a clone of this functor.
Implements lti::panTiltUnit.
int lti::directedPerceptionPTU::convertValueToPTUnits | ( | float | position | ) | [protected] |
Converts a given pan or tilt position into the internal PTU-format depending on the position mode.
directedPerceptionPTU& lti::directedPerceptionPTU::copy | ( | const directedPerceptionPTU & | other | ) |
Copy data of "other" functor.
other | the functor to be copied |
Reimplemented from lti::panTiltUnit.
void lti::directedPerceptionPTU::emptySerialBuffer | ( | ) | [protected] |
Useful method, which simply reads out the serial buffer until it is empty to ensure, that nothing is in it before starting work on the buffer.
float lti::directedPerceptionPTU::getCurrentPan | ( | ) |
Reads out physically occuring pan axis position from the pan-tilt unit and store it in the given reference parameter.
Depending on the current angle format the value contains the absolute position in degrees or radiants. It is always in absolute position, independent from position mode. Note that the internal pan and tilt positions could differ very much from the physical ones, if you apply a large amount of relative position commands shortly after each other. You can update the internal values by using directedPerceptionPTU::updatePanTilt(). This method uses the directedPerceptionPTU::isIdlePTU() to determine, if the unit is still performig commands. If so, the positions can not be read out.
bool lti::directedPerceptionPTU::getCurrentPanTilt | ( | float & | pan, | |
float & | tilt | |||
) |
Reads out physically occuring pan and tilt axis positions from the pan-tilt unit and stores them in the given reference parameters.
Depending on the current angle format the values contain the absolute positions in degrees or radiants. They are always in absolute positions, independent from position mode. Note that the internal pan and tilt positions could differ very much from the physical ones, if you apply a large amount of relative position commands shortly after each other. You can update the internal values by using directedPerceptionPTU::updatePanTilt(). This method uses the directedPerceptionPTU::isIdlePTU() to determine, if the unit is still performing commands. If so, the positions can not be read out.
float lti::directedPerceptionPTU::getCurrentTilt | ( | ) |
Reads out physically occuring tilt axis position from the pan-tilt unit and store it in the given reference parameter.
Depending on the current angle format the value contains the absolute position in degrees or radiants. It is always in absolute position, independent from position mode. Note that the internal pan and tilt positions could differ very much from the physical ones, if you apply a large amount of relative position commands shortly after each other. You can update the internal values by using directedPerceptionPTU::updatePanTilt(). This method uses the directedPerceptionPTU::isIdlePTU() to determine, if the unit is still performig commands. If so, the positions can not be read out.
float lti::directedPerceptionPTU::getMaxPanAcceleration | ( | ) |
Gets maximum pan acceleration in the desired angle format.
float lti::directedPerceptionPTU::getMaxPanSpeed | ( | ) |
Gets maximum pan speed in the desired angle format.
float lti::directedPerceptionPTU::getMaxTiltAcceleration | ( | ) |
Gets maximum tilt acceleration in the desired angle format.
float lti::directedPerceptionPTU::getMaxTiltSpeed | ( | ) |
Gets maximum tilt speed in the desired angle format.
float lti::directedPerceptionPTU::getMinPanAcceleration | ( | ) |
Gets minimum pan acceleration in the desired angle format.
float lti::directedPerceptionPTU::getMinPanSpeed | ( | ) |
Gets minimum pan speed in the desired angle format.
float lti::directedPerceptionPTU::getMinTiltAcceleration | ( | ) |
Gets minimum tilt acceleration in the desired angle format.
float lti::directedPerceptionPTU::getMinTiltSpeed | ( | ) |
Gets minimum tilt speed in the desired angle format.
float lti::directedPerceptionPTU::getPan | ( | ) | const [virtual] |
Get internal pan position.
Depending on the current angle format the value is returned in radiants or degrees. They are always in absolute positions, independent from position mode. Note that the internal pan and tilt positions could differ very much from the physical ones, if you apply a large amount of relative position commands shortly after each other. You can update the internal values by using directedPerceptionPTU::updatePanTilt().
Implements lti::panTiltUnit.
bool lti::directedPerceptionPTU::getPanTilt | ( | float & | pan, | |
float & | tilt | |||
) | const [virtual] |
Get internal pan and tilt positions.
Depending on the current angle format the values are stored in the given reference parameters in radiants or degrees. Note that the internal pan and tilt positions could differ very much from the physical ones, if you apply a large amount of relative position commands shortly after each other. You can update the internal values by using directedPerceptionPTU::updatePanTilt().
Implements lti::panTiltUnit.
const parameters& lti::directedPerceptionPTU::getParameters | ( | ) | const |
Returns used parameters.
Reimplemented from lti::panTiltUnit.
float lti::directedPerceptionPTU::getTilt | ( | ) | const [virtual] |
Get internal tilt position.
Depending on the current angle format the value is returned in radiants or degrees. It is always in absolute position, independent from position mode. Note that the internal pan and tilt positions could differ very much from the physical ones, if you apply a large amount of relative position commands shortly after each other. You can update the internal values by using directedPerceptionPTU::updatePanTilt().
Implements lti::panTiltUnit.
virtual const char* lti::directedPerceptionPTU::getTypeName | ( | ) | const [virtual] |
Returns the name of this type ("DirectedPerceptionPTU").
Reimplemented from lti::panTiltUnit.
parameters& lti::directedPerceptionPTU::getWritableParameters | ( | ) | [protected] |
bool lti::directedPerceptionPTU::initialize | ( | ) |
Tests connection to pan-tilt unit and sets initial speeds, acceleration and position.
Reimplemented from lti::object.
bool lti::directedPerceptionPTU::isPTUidle | ( | ) |
Determine whether the pan-tilt unit is still performing commands.
That means, that at the moment at maximum one command is executed, which is not a position command followed by an await instruction.
directedPerceptionPTU& lti::directedPerceptionPTU::operator= | ( | const directedPerceptionPTU & | other | ) |
Alias for copy member.
other | the functor to be copied |
Reimplemented from lti::panTiltUnit.
bool lti::directedPerceptionPTU::reset | ( | ) | [virtual] |
Reset the pan-tilt unit.
Forces the pan-tilt unit to drive through its pan and tilt axis to determine min/max positions. After that pan-tilt position 0,0 is applied.
Implements lti::panTiltUnit.
bool lti::directedPerceptionPTU::setAngleFormat | ( | parameters::eAngleFormatType | anAngleFormat | ) |
Sets angle format to degrees or radiants.
bool lti::directedPerceptionPTU::setAutoscan | ( | ) |
Enables autoscan with the last applied autoscan parameters .
In autoscan or monitor mode the pan-tilt unit keeps moving between the given pan and/or tilt positions until another position command or directedPerceptionPTU::stopAutoscan() is applied. Through this method the unit is instructed to move between pan and tilt positions given, when executing autoscan the last time. If it was not enabled before the pan-tilt unit starts moving between max and min pan positions in current pan speed and acceleration. Autoscan is only available in absolute positions. Please, make sure you stop autoscan with directedPerceptionPTU::stopAutoscan(). This is saver than by applying further position commands. If the given values are not within maximum and minimum pan/tilt range, max/min positions are applied.
bool lti::directedPerceptionPTU::setAutoscan | ( | float | panPos1, | |
float | panPos2, | |||
float | tiltPos1, | |||
float | tiltPos2 | |||
) |
Enables autoscan in pan and tilt direction.
In autoscan or monitor mode the pan-tilt unit keeps moving between the given pan and/or tilt positions until another position command or directedPerceptionPTU::stopAutoscan() is applied. Through this method the unit is instructed to move between panPos1 and panPos2 and between tiltPos1 and tilt Pos2 with current pan/tilt speeds/accelerations. Autoscan is only available in absolute positions. Please, make sure you stop autoscan with directedPerceptionPTU::stopAutoscan(). This is saver than by applying further position commands. If the given values are not within maximum and minimum pan/tilt range, max/min positions are applied.
bool lti::directedPerceptionPTU::setAutoscan | ( | float | panPos1, | |
float | panPos2 | |||
) |
Enables autoscan in pan direction.
In autoscan or monitor mode the pan-tilt unit keeps moving between the given pan and/or tilt positions until another position command or directedPerceptionPTU::stopAutoscan() is applied. Through this method the unit is instructed to move between panPos1 and panPos2 with the current pan speed and pan acceleration. Autoscan is only available in absolute positions. Please, make sure you stop autoscan with directedPerceptionPTU::stopAutoscan(). This is saver than by applying further position commands. If the given values are not within maximum and minimum pan range, max/min positions are applied.
bool lti::directedPerceptionPTU::setExecMode | ( | parameters::eExecModes | anExecMode | ) |
Sets command execution mode to immidiate or slaved.
bool lti::directedPerceptionPTU::setPan | ( | float | pan | ) | [virtual] |
Set desired pan position.
If the given pan position, which could be set in radiants or degrees, is within minimum/maximum range the pan-tilt unit will drive there. If the value is out of range, max or min position is applied. This will be commented in the status string. Depending on posMode the position can be set in absolute or relative angle parameters. Notise, that pan-tilt position commands in the slaved execution mode are only applied, when the directedPerceptionPTU::awaitPosCommandCompletion() method is called after setting pan-tilt. If you give more than one pan-tilt combination in slaved mode before calling await method, only the last will be executed.
Implements lti::panTiltUnit.
bool lti::directedPerceptionPTU::setPanAcceleration | ( | float | panAcc | ) |
Sets the pan acceleration to the desired value panAcc, which can be given in radiants or degrees.
It is always interpreted as absolute setting, independent from position mode. If it is between allowed minimum and maximum pan acceleration, the change is dircetly taken over. If the value is out of range max respectively min pan acceleration is applied. This case is indicated by setting the status string.
bool lti::directedPerceptionPTU::setPanSpeed | ( | float | panSpeed | ) |
Sets the pan speed to the desired value panSpeed, which can be given in radiants or degrees.
It is always interpreted as absolute setting, independent from position mode. If it is between allowed minimum and maximum speed, the change is dircetly taken over. If the value is out of range max respectively min speed is applied. This case is indicated by setting the status string.
bool lti::directedPerceptionPTU::setPanTilt | ( | float | pan, | |
float | tilt | |||
) | [virtual] |
Set desired pan-tilt position.
If the given pan and tilt positions, which could be set in radiants or degrees, are within minimum/maximum range the pan-tilt unit will drive there. If the values are out of range, max or min positions are applied. This will be commented in the status string. Depending on posMode the position can be set in absolute or relative angle parameters. Notise, that pan-tilt position commands in the slaved execution mode are only applied, when the directedPerceptionPTU::awaitPosCommandCompletion() method is called after setting pan-tilt. If you give more than one pan-tilt combination in slaved mode before calling await method, only the last will be executed.
Implements lti::panTiltUnit.
bool lti::directedPerceptionPTU::setPosMode | ( | parameters::ePosModes | anPosMode | ) |
Sets position mode to absolute or relative.
bool lti::directedPerceptionPTU::setTilt | ( | float | tilt | ) | [virtual] |
Set desired tilt position If the given tilt position, which could be set in radiants or degrees, is within minimum/maximum range the pan-tilt unit will drive there.
If the value is out of range, max or min position is applied. This will be commented in the status string. Depending on posMode the position can be set in absolute or relative angle parameters. Notise, that pan-tilt position commands in the slaved execution mode are only applied, when the directedPerceptionPTU::awaitPosCommandCompletion() method is called after setting pan-tilt. If you give more than one pan-tilt combination in slaved mode before calling await method, only the last will be executed.
Implements lti::panTiltUnit.
bool lti::directedPerceptionPTU::setTiltAcceleration | ( | float | tiltAcc | ) |
Sets the tilt acceleration to the desired value panAcc, which can be given in radiants or degrees.
It is always interpreted as absolute setting, independent from position mode. If it is between allowed minimum and maximum acceleration, the change is dircetly taken over. If the value is out of range max respectively min tilt acceleration is applied. This case is indicated by setting the status string.
bool lti::directedPerceptionPTU::setTiltSpeed | ( | float | tiltSpeed | ) |
Sets the tilt speed to the desired value panSpeed, which can be given in radiants or degrees.
It is always interpreted as absolute setting, independent from position mode. If it is between allowed minimum and maximum speed, the change is dircetly taken over. If the value is out of range max respectively min tilt speed is applied. This case is indicated by setting the status string.
bool lti::directedPerceptionPTU::stopAutoscan | ( | ) |
bool lti::directedPerceptionPTU::stopPan | ( | ) |
Stop pan movement.
The pan-tilt unit freezes at its current pan position.
bool lti::directedPerceptionPTU::stopPanTilt | ( | ) | [virtual] |
Stop all movement of the pan-tilt unit.
The pan-tilt unit freezes at its current pan and tilt position.
Implements lti::panTiltUnit.
bool lti::directedPerceptionPTU::updatePanTilt | ( | ) |
Reads out the current pan and tilt positions from the PTU and overrides the internal values.
The method uses directedPTU::getCurrentPanTilt() to get the physically positions.
Note that the update can only be performed, if the pan-tilt unit is idle. That means, that at the moment at maximum one command is executed, which is not a position command followed by an await instruction.