Module: AxisNetcam::Camera::PTZ

Included in:
AxisNetcam::Camera
Defined in:
lib/axis-netcam/camera.rb

Overview

Functionality related to the camera’s point, zoom, and tilt. Not all camera models support this.

Instance Method Summary collapse

Instance Method Details

#calibrateObject

Tries to ‘calibrate’ the camera by rotating to all extremes.

This may be useful when the camera is shifted by some external force and looses its place. Running the calibration should reset things so that the camera’s absolute point and tilt co-ordinates are consistent relative to the camera’s base.



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/axis-netcam/camera.rb', line 191

def calibrate
  @log.info("Starting camera calibration...")
  
  pos = get_position
  limits = get_ptz_limits(:auto)
  
  zoom(limits['MinZoom'])
  (1..2).each do # do it twice, just to be safe...
    sleep(3)
    ptz(:pan => limits['MinPan'], :tilt => limits['MinTilt'])
    sleep(7)
    ptz(:pan => limits['MinPan'], :tilt => limits['MaxTilt'])
    sleep(7)
    ptz(:pan => limits['MaxPan'], :tilt => limits['MaxTilt'])
    sleep(7)
    ptz(:pan => limits['MaxPan'], :tilt => limits['MinTilt'])
    sleep(7)
  end
  
  ptz(pos)
  
  @log.info("Finished camera calibration.")
end

#center_on(x, y) ⇒ Object

Zooms the camera (in/out) to the given zoom factor.



116
117
118
# File 'lib/axis-netcam/camera.rb', line 116

def center_on(x,y)
  axis_action("com/ptz.cgi", {'center'  => "#{x},#{y}"})
end

#get_positionObject

Returns the camera’s current absolute position as a hash with :pan, :tilt, and :zoom elements.

:tilt and :pan are specified in degrees from center (for example, -170 to 170 for :pan, depending on your camera’s physical capabilities), and zoom is an integer factor, with 0 being no zoom (widest possible viewing angle) and 10000 approaching a camera’s maximum zoom. Again, this depends on your camera’s capabilities.



78
79
80
81
82
83
84
85
86
# File 'lib/axis-netcam/camera.rb', line 78

def get_position
  raw = axis_action("com/ptz.cgi", {'query' => 'position'})
  str = raw.split
  pan = str[0].split("=").last.to_f
  tilt = str[1].split("=").last.to_f
  zoom = str[2].split("=").last.to_i
  
  {:pan => pan, :tilt => tilt, :zoom => zoom}
end

#get_preset_positionsObject

Returns and array with the names of the preset positions saved in the camera.



121
122
123
124
125
126
127
128
129
# File 'lib/axis-netcam/camera.rb', line 121

def get_preset_positions
  str = axis_action("com/ptz.cgi", {'query' => 'presetposall'})
  positions = []
  str.each do |line|
    line =~ /presetposno\d+=(.*)/
    positions << $~[1].strip if $~ && $~[1]
  end
  positions
end

#get_ptz_limits(rotation = nil) ⇒ Object

Returns a hash with info about the camera’s point-tilt-zoom limits.

The returned hash will look something like:

{'MinPan' => "-169",
 'MaxPan' => "169",
 'MinTilt' => "-90",
 'MaxTilt' => "10",
 'MinZoom' => "1",
 'MaxZoom' => "19999"}

The pan and tilt limit values assume that your camera’s image is not rotated. If you want to use these values in ptz calls and your image is configured to be rotated, then you should also specify :imagerotation => 0 as one of your parameters to ptz. For example:

limits = c.get_ptz_limits
c.ptz(:tilt => limits['MaxTilt'], :imagerotation => 0)

Alternatively, you can specify a rotation argument. This will automatically adjust the returned pan and tilt values to match the given rotation. You can also specify :auto instead of providing a numeric value, in which case the system will try to fetch the rotation value for you (but be careful, because this can slow things down, since the camera must be queried first).



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/axis-netcam/camera.rb', line 157

def get_ptz_limits(rotation = nil)
  l = get_parameters("PTZ.Limit.L1")
  return l unless rotation
  
  rotation = get_current_image_rotation if rotation == :auto
  
  # TODO: this only works for the 0, 90, 180, 270 rotations but not arbitrary values
  case rotation
  when 90
    l['MinPan'], l['MaxPan'], l['MinTilt'], l['MaxTilt'] =
    l['MinTilt'], l['MaxTilt'], l['MinPan'], l['MaxPan']
  when 180
    l['MinPan'], l['MaxPan'], l['MinTilt'], l['MaxTilt'] =
    l['MinPan'], l['MaxPan'], l['MaxTilt']*-1, l['MinTilt']*-1
  when 270
    # FIXME: This transformation appears to be busted :(
    l['MinPan'], l['MaxPan'], l['MinTilt'], l['MaxTilt'] =
    l['MinTilt'], l['MaxTilt'], l['MinPan']*-1, l['MaxPan']*-1
  end
  
  l
end

#pan(d) ⇒ Object

Pans the camera (left/right) to the given absolute position in degrees.



106
107
108
# File 'lib/axis-netcam/camera.rb', line 106

def pan(d)
  axis_action("com/ptz.cgi", {'pan'  => d})
end

#point_at_preset_name(preset_name) ⇒ Object

Points the camera at the given preset.



181
182
183
# File 'lib/axis-netcam/camera.rb', line 181

def point_at_preset_name(preset_name)
  axis_action("com/ptz.cgi", {'gotoserverpresetname' => preset_name})
end

#ptz(ptz = {}) ⇒ Object

Simultanously pans, tilts, and zooms the camera. The argument is a hash that can have any of ‘pan’, ‘tilt’, and ‘zoom’ elements, each specifying the desired value for the movement.

Example:

camera.ptz(:pan => 60, :zoom => 8000)


96
97
98
# File 'lib/axis-netcam/camera.rb', line 96

def ptz(ptz = {})
  axis_action('com/ptz.cgi', ptz)
end

#tilt(d) ⇒ Object

Tilts the camera (up/down) to the given absolute position in degrees.



101
102
103
# File 'lib/axis-netcam/camera.rb', line 101

def tilt(d)
  axis_action("com/ptz.cgi", {'tilt'  => d})
end

#zoom(n) ⇒ Object

Zooms the camera (in/out) to the given zoom factor.



111
112
113
# File 'lib/axis-netcam/camera.rb', line 111

def zoom(n)
  axis_action("com/ptz.cgi", {'zoom'  => n})
end