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.



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/axis-netcam/camera.rb', line 197

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.



122
123
124
# File 'lib/axis-netcam/camera.rb', line 122

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.



127
128
129
130
131
132
133
134
135
# File 'lib/axis-netcam/camera.rb', line 127

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).



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/axis-netcam/camera.rb', line 163

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

#move(direction) ⇒ Object

Move the camera one ‘tick’ in the given direction. Possible values are ‘up’, ‘down’, ‘left’, ‘right’



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

def move(direction)
  axis_action("com/ptz.cgi", {'move' => direction})
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.



187
188
189
# File 'lib/axis-netcam/camera.rb', line 187

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.



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

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