Module: ARbDrone::Control

Defined in:
lib/arbdrone/control.rb

Constant Summary collapse

REF_CONST =

With SDK version 1.5, only bits 8 and 9 are used in the control bit-field. Bits 18, 20, 22, 24 and 28 should be set to 1. Other bits should be set to 0.

290717696
CONTROL_MODES =
{
  :none            => 0, # Doing nothing
  :ardone_update   => 1, # Deprecated - AR.Drone software update reception (update is done next run). After event completion, card should be powered off.
  :pic_update      => 2, # AR.Drone PIC software update reception (update is done next run)
  :get_log         => 3, # Send previous run's logs
  :get_cfg         => 4, # Send active configuration file to a client through the 'control' TCP socket
  :ack             => 5, # Reset command mask in NavData
  :custom_cfg_get  => 6, # Send list of custom configuration IDs
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#seqObject

Returns the value of attribute seq.



23
24
25
# File 'lib/arbdrone/control.rb', line 23

def seq
  @seq
end

Instance Method Details



122
123
124
# File 'lib/arbdrone/control.rb', line 122

def blink(animation, frequency, duration)
  push format_cmd 'AT*LED', "#{animation},#{float2int frequency},#{duration}"
end

#config_ids(sess_id, user_id, app_id) ⇒ Object



105
106
107
# File 'lib/arbdrone/control.rb', line 105

def config_ids(sess_id, user_id, app_id)
  push format_cmd 'AT*CONFIG_IDS', "#{sess_id},#{user_id},#{app_id}"
end

#dance(animation, duration) ⇒ Object



126
127
128
# File 'lib/arbdrone/control.rb', line 126

def dance(animation, duration)
  push format_cmd 'AT*ANIM', "#{animation},#{duration}"
end

#drone_control(mode, something = 0) ⇒ Object



113
114
115
116
# File 'lib/arbdrone/control.rb', line 113

def drone_control(mode, something = 0)
  # FIXME: What is the purpose of the second argument?
  push format_cmd 'AT*CTRL', "#{mode},#{something}"
end

#float2int(float) ⇒ Object



142
143
144
# File 'lib/arbdrone/control.rb', line 142

def float2int(float)
  [float.to_f].pack('e').unpack('l').first
end

#format_cmd(cmd, data = nil) ⇒ Object



72
73
74
# File 'lib/arbdrone/control.rb', line 72

def format_cmd(cmd, data = nil)
  "#{cmd}=#{next_seq},#{data}\r"
end

#heartbeatObject



118
119
120
# File 'lib/arbdrone/control.rb', line 118

def heartbeat
  push format_cmd 'AT*COMWDG'
end

#hoverObject



89
90
91
92
93
# File 'lib/arbdrone/control.rb', line 89

def hover
  # Set bit zero to zero to make the drone enter hovering mode
  flags = 0
  push format_cmd *pcmd(flags, 0, 0, 0, 0)
end

#landObject



85
86
87
# File 'lib/arbdrone/control.rb', line 85

def land
  @drone_state = 0
end

#minmax(min, max, *args) ⇒ Object



163
164
165
# File 'lib/arbdrone/control.rb', line 163

def minmax(min, max, *args)
  args.map {|arg| arg < min ? min : arg > max ? max : arg }
end

#next_seqObject



68
69
70
# File 'lib/arbdrone/control.rb', line 68

def next_seq
  @seq = @seq.nil? ? 1 : @seq + 1
end

#pcmd(flags, phi, theta, gaz, yaw) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/arbdrone/control.rb', line 146

def pcmd(flags, phi, theta, gaz, yaw)
  values = [flags]

  # Ensure the inputs do not exceed [-1.0, 1.0]
  phi, theta, gaz, yaw = minmax -1.0, 1.0, phi, theta, gaz, yaw

  # Convert the values to IEEE 754, then cast to a signed int
  values += [phi, theta, gaz, yaw].map { |v|
    float2int v
  }
  ['AT*PCMD', values.join(',')]
end

#push(msg) ⇒ Object Also known as: <<



48
49
50
# File 'lib/arbdrone/control.rb', line 48

def push(msg)
  @send_queue << msg
end

#ref(input) ⇒ Object



130
131
132
# File 'lib/arbdrone/control.rb', line 130

def ref(input)
  ['AT*REF', input |= REF_CONST]
end

#reset_trimObject



101
102
103
# File 'lib/arbdrone/control.rb', line 101

def reset_trim
  push format_cmd 'AT*FTRIM'
end

#send_queued_messagesObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/arbdrone/control.rb', line 53

def send_queued_messages
  msg = ''
  until (@send_queue.empty? || (msg.length + @send_queue.first.length) >= 1024) do
    msg << @send_queue.shift
  end
  if msg.empty?
    send_datagram state_msg, @drone_ip, @drone_control_port
  else
    # Send control input
    @send_mutex.synchronize do
      send_datagram(msg, @drone_ip, @drone_control_port) unless msg.empty?
    end
  end
end

#set_option(name, value) ⇒ Object



109
110
111
# File 'lib/arbdrone/control.rb', line 109

def set_option(name, value)
  push format_cmd 'AT*CONFIG', "\"#{name}\",\"#{value}\""
end

#setup(drone_ip, drone_control_port, options = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/arbdrone/control.rb', line 25

def setup(drone_ip, drone_control_port, options = {})
  @drone_ip, @drone_control_port = drone_ip, drone_control_port
  @send_queue = []
  @send_mutex = Mutex.new

  @application_id = options.delete(:application_id) || 'ARbDrone'
  @user_id        = options.delete(:user_id)        || Etc.getlogin
  @session_id     = options.delete(:session_id)     || "#{Socket.gethostname}:#{$$}"

  # FIXME: Do we want to send these commands? These are not well documented.
  # The following three lines are sent by the Linux example utility, ardrone_navigation
  # as the first three messages sent to the drone at initialization.
  #push format_cmd 'AT*PMODE', 2
  #push format_cmd 'AT*MISC', '2,20,2000,3000'
  #hover

  # Inform the Drone who we are
  config_ids @session_id, @user_id, @application_id

  # Invalidate all other controller sessions
  set_option 'custom:session_id', '-all'
end

#shutdown!Object



159
160
161
# File 'lib/arbdrone/control.rb', line 159

def shutdown!
  @seq = nil
end

#state_msgObject

Used primarily to keep the control connection alive The drone expects a packet at least every 50ms or it triggers the watchdog. After 2 seconds the connection is considered lost.



138
139
140
# File 'lib/arbdrone/control.rb', line 138

def state_msg
  format_cmd *ref(@drone_state)
end

#steer(phi, theta, gaz, yaw) ⇒ Object



95
96
97
98
99
# File 'lib/arbdrone/control.rb', line 95

def steer(phi, theta, gaz, yaw)
  # Set bit zero to one to make the drone process inputs
  flags = 1 << 0
  push format_cmd *pcmd(flags, phi, theta, gaz, yaw)
end

#takeoffObject



80
81
82
83
# File 'lib/arbdrone/control.rb', line 80

def takeoff
  # Bit 9 is 1 for takeoff
  @drone_state |= 1 << 9
end

#toggle_stateObject



76
77
78
# File 'lib/arbdrone/control.rb', line 76

def toggle_state
  push format_cmd *ref(1<<8)
end