crubyflie 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9f8c948aed7ee8dc5776a9d2b26ceb5ce6673792
4
- data.tar.gz: 6314537e66334c3e403142c0c217af9bb832d54a
3
+ metadata.gz: 02c5195ea21e56d89557355913944da49b894f21
4
+ data.tar.gz: 92b4e05341df2db63e05149e82b17099d5015eb3
5
5
  SHA512:
6
- metadata.gz: cbc016920486d8c234bf3efdc78f895dd70d38ad61f128afca3a80521efb8cfc758ab07441dec8e54e9168285f71f2b0d1d9c48f97f36ab0a1b0f4f6376bbc60
7
- data.tar.gz: 2478f8cdcf14a77fdfbab4eaad8b6477916c9c4cee8cc92af55afe34214b48caba7a7aa8aa6a1ffb72f8074f705c64bbdd9fe62cb73c8b3a102c96c357c9e469
6
+ metadata.gz: a141f33049bae4a6bb67a80164514d42141cc303d66d460a0b3987c73c716ecd3ce2bbd5d181cc69f706ca3dc933f5de479e32f5fb8a6ffd32956b016468d805
7
+ data.tar.gz: a34a3b8d723f5154d2f71753f3345d25d42d6b54d818d47b5d7f13edf344125268d1c69c48c4184805dde548e7950f3a250b0876300d8dda5807ed94f9ed5688
data/README.md CHANGED
@@ -33,10 +33,19 @@ Not included...
33
33
  * No idea how this works in other OSs that are not Linux, but in theory it should work in all with some small fixes. I welcome you to take on this task if you are interested.
34
34
  * No support for Ruby <= 1.8.7 (maybe it works who knows... I haven't tested but since Crubyflie relies heavily on threading probably it does not work so good).
35
35
 
36
+ Installation
37
+ ------------
38
+
39
+ Crubyflie depends on `rubysdl`, for which you will need the SDL library and headers. Make sure you install `libsdl-dev` (Debian/Ubuntu), `libSDL-devel` (Opensuse) or whatever your distro calls it. Then:
40
+
41
+ gem install crubyflie
42
+
43
+ That's all.
44
+
36
45
  Fyling the Crazyflie
37
46
  --------------------
38
47
 
39
- The easiest way to do it is to run the `crubyflie` command. This will connect to the first visible quadcopter using the first available joystick on your computer (you can modify this parameters with the appropiate flags):
48
+ The easiest way to do it is to `gem install crubyflie` and then run the `crubyflie` command. This will connect to the first visible quadcopter using the first available joystick on your computer (you can modify this parameters with the appropiate flags):
40
49
 
41
50
  > crubyflie2.0 -h
42
51
  Options:
@@ -46,13 +55,13 @@ The easiest way to do it is to run the `crubyflie` command. This will connect to
46
55
  /usr/lib64/ruby/gems/2.0.0/gems/crubyflie-0.0.1/lib/crubyflie/input/../../../configs/joystick_default.yaml)
47
56
  --help, -h: Show this message
48
57
 
49
- A template/default configuration file (which works for me and my PS3-like controller :)) is provided with the gem (in the `configs/` folder). You should modify this file to fit it to your needs (configuration parameters are commented). The most tricky parameter in axis is the `:max_change_rate`. Depending on your controller, you will find the input is excessively throotled or not. I recommend that you play with this value.
58
+ There is a [template/default configuration file](https://github.com/hsanjuan/crubyflie/blob/master/configs/joystick_default.yaml) with instructions (which works for me and my PS3-like controller :) ). You should modify this file to fit it to your needs (configuration parameters are commented). The most tricky parameter in axis is the `:max_change_rate`. Depending on your controller, you will find the input is excessively throotled or not. I recommend that you play with this value.
50
59
 
51
60
  If you are wondering about your Joystick's axis IDs, ranges etc, you will find a `sdl-joystick-axis.rb` script under `tools` that lets you open a joystick and check what the SDL library can read from it. It might come handy.
52
61
 
53
62
  If you need help just open an issue or contact me.
54
63
 
55
- Raspberri Pi
64
+ Raspberry Pi
56
65
  ------------
57
66
 
58
67
  If you want to use Crubyflie in your Raspberry Pi you need to:
data/bin/crubyflie CHANGED
@@ -36,11 +36,13 @@ opts = Trollop::options do
36
36
  :type => :string,
37
37
  :default => Crubyflie::Joystick::DEFAULT_CONFIG_PATH,
38
38
  :short => '-c')
39
- end
39
+ opt(:debug, "Enable debug messages",
40
+ :short => '-d')
41
+ end
40
42
 
41
43
  include Crubyflie
42
- # Uncomment to turn on debugging
43
- # $debug = true
44
+ $debug = true if opts[:debug]
45
+
44
46
  cf = Crazyflie.new('/tmp/crubyflie')
45
47
 
46
48
  # Before opening any link, scan for interfaces
@@ -80,7 +82,7 @@ while cf.active? && !exit do
80
82
  # 1/10 secs of time per loop. If we are fast, we can sleep
81
83
  # a little bit
82
84
  consumed_time = Time.now.to_f - start_time
83
- sleep_time = 0.1 - (consumed_time)
85
+ sleep_time = 0.1 - consumed_time
84
86
  sleep sleep_time if sleep_time > 0
85
87
  end
86
88
 
@@ -1,5 +1,58 @@
1
- # Default joystick configuration file. It mimics the PS3_Mode2 original
2
- # configuration file
1
+ # Default joystick configuration file. A file looks like:
2
+ # --------------------------------------------------------------------------
3
+ # :type: Joystick
4
+ # :axis:
5
+ # <axis_id>:
6
+ # :action: <action>
7
+ # :description: A short description to remember what this is
8
+ # :input_range: "<start>:<end>"
9
+ # The range read from the joystick.
10
+ # Defaults to -32768:32767 which is SDL-dependant
11
+ #
12
+ # :output_range: "<start>:<end>"
13
+ # The values we should yield to
14
+ # the Crazyflie, normally degrees (roll, pitch...). For
15
+ # thrust it is expressed in % of thrust
16
+ #
17
+ # :max_change_rate: <number>
18
+ # The output_range change rate per second. Must
19
+ # e a number. Defaults to 10000 (so a lot). For thrust
20
+ # it is expressed in % of thrust
21
+ # :dead_zone: "<start>:<end>"
22
+ # The dead range around 0. Defaults to 0:0
23
+ #
24
+ # :invert: true|false - Invert this axis
25
+ #
26
+ # :calibration: <number>
27
+ # This value is added to the raw joystick reading
28
+ #
29
+ # <axis_id2>: ...
30
+ #
31
+ # :buttons:
32
+ # <button_id>:
33
+ # :action: <action>
34
+ # :value: <value when pressed>
35
+ # A number, optional, defaults to 1.
36
+ #
37
+ # <button_id2>: ...
38
+ #
39
+ # --------------------------------------------------------------------------
40
+ # Valid actions:
41
+ # :roll - Controls roll. Assignable a axis or a button with value tag.
42
+ # :pitch - Controls pitch. Assignable a axis or a button with value tag.
43
+ # :thrust - Controls thrust. Assignable a axis or a button with value tag.
44
+ # :yaw - Controls yaw. Assignable a axis or a button with value tag.
45
+ # :switch_xmode - Enables/disables xmode. Assignable to a button.
46
+ # :close_link - Kills the link and shuts Crubyflie. Assignable to a button.
47
+ # :switch_scaled_output_mode - Enables/disabled scaled output mode. Assignable
48
+ # to a button with value tag (the multiplier)
49
+ # :roll_inc_cal, :roll_dec_cal - Increase/decrease calibration for :roll axis.
50
+ # Assignable to a button with optional value.
51
+ #
52
+ # :pitch_inc_cal, :pitch_dec_cal - Increase/decrease calibration for :pitch
53
+ # axis. Assignable to a button with optional
54
+ # value.
55
+ # ---------------------------------------------------------------------------
3
56
  :type: "Joystick"
4
57
  :axis:
5
58
  0:
@@ -24,7 +77,7 @@
24
77
  :description: "Yaw Axis"
25
78
  :action: :yaw
26
79
  :input_range: "-32768:32767"
27
- :output_range: "-200:200"
80
+ :output_range: "-150:150"
28
81
  :max_change_rate: 800
29
82
  :dead_zone: "-1000:1000"
30
83
  :invert: false
@@ -33,11 +86,11 @@
33
86
  :description: "Thrust axis"
34
87
  :action: :thrust
35
88
  :input_range: "-32768:32767"
36
- :output_range: "0:80" # Exception: Min/max thrust output is represented in 0-100%!
37
- # Max change rate per second when lowering thrust. Note that this
38
- # is a change ranging between ranges 9500 and 60000
39
- :max_change_rate: 40000
40
- :dead_zone: "-100:100" # Deadzone, within input range
89
+ # Exception: Min/max thrust output is represented in 0-100%!
90
+ :output_range: "0:80"
91
+ # Max change rate per second when lowering thrust in % of thrust
92
+ :max_change_rate: 70
93
+ :dead_zone: "-100:100"
41
94
  :invert: true
42
95
  :calibration: 0
43
96
 
@@ -45,4 +98,9 @@
45
98
  0:
46
99
  :action: :switch_xmode
47
100
  1:
48
- :action: :close_link
101
+ :action: :close_link
102
+ 4:
103
+ # When enabled, this mode will will multiply axis readings (except thrust)
104
+ # by the value of the button (must be a positive number)
105
+ :action: :switch_scaled_output_mode
106
+ :value: 0.50 # Softer output, useful for landing
@@ -30,31 +30,32 @@ module Crubyflie
30
30
  #
31
31
  # The InputReader will also apply the #INPUT_ACTIONS to a given
32
32
  # Crazyflie. In order to do that it will go through all the
33
- # read values and perform actioins associated to them, like sending
34
- # a setpoint or shutting down the connection or altering the calibration.
33
+ # read values and perform actions associated to them, like sending
34
+ # a setpoint, shutting down the connection or altering the calibration.
35
35
  class InputReader
36
36
 
37
37
  # List of current recognized actions that controllers can declare
38
38
  INPUT_ACTIONS = [:roll, :pitch, :yaw, :thrust,
39
39
  :roll_inc_cal, :roll_dec_cal,
40
40
  :pitch_inc_cal, :pitch_dec_cal,
41
+ :switch_scaled_output_mode,
41
42
  :switch_xmode, :close_link]
42
43
 
43
44
  attr_reader :axis, :buttons, :axis_readings, :button_readings
44
45
  attr_accessor :xmode
45
- # An input is composed by several necessary axis, buttons and
46
- # calibrations.
46
+ # An input is composed by several necessary axis and buttons.
47
47
  # @param axis [Hash] A hash of keys identifying axis IDs
48
48
  # (the controller should know to what the
49
- # ID maps, and values from #INPUT_ACTIONS
49
+ # ID maps), and values from #INPUT_ACTIONS
50
50
  # @param buttons [Hash] A hash of keys identifying button IDs (the
51
- # controller should know to what the ID maps,
51
+ # controller should know to what the ID maps),
52
52
  # and values from #INPUT_ACTIONS
53
53
  def initialize(axis, buttons)
54
54
  @axis = axis
55
55
  @buttons = buttons
56
56
  @calibrations = {}
57
57
  @xmode = false
58
+ @output_scale = 0 # off
58
59
 
59
60
  # Calibrate defaults to 0
60
61
  INPUT_ACTIONS.each do |action|
@@ -73,12 +74,20 @@ module Crubyflie
73
74
  poll() # In case we need to poll the device
74
75
  actions_to_axis = @axis.invert()
75
76
  actions_to_axis.each do |action, axis_id|
77
+ if !INPUT_ACTIONS.include?(action)
78
+ logger.error("Unknown action #{action}. Skipping")
79
+ next
80
+ end
76
81
  @axis_readings[action] = read_axis(axis_id)
77
82
  @axis_readings[action] += @calibrations[action]
78
83
  end
79
84
 
80
85
  actions_to_buttons = @buttons.invert()
81
86
  actions_to_buttons.each do |action, button_id|
87
+ if !INPUT_ACTIONS.include?(action)
88
+ logger.error("Unknown action #{action}. Skipping")
89
+ next
90
+ end
82
91
  @button_readings[action] = read_button(button_id)
83
92
  @button_readings[action] += @calibrations[action]
84
93
  end
@@ -86,7 +95,7 @@ module Crubyflie
86
95
 
87
96
  # This will act on current axis readings (by sendint a setpoint to
88
97
  # the crazyflie) and on button readings (by, for example, shutting
89
- # down the link or modifying the calibrations.
98
+ # down the link or modifying the calibrations).
90
99
  # If the link to the crazyflie is down, it will not send anything.
91
100
  # @param crazyflie [Crazyflie] A crazyflie instance to send the
92
101
  # setpoint to.
@@ -120,6 +129,14 @@ module Crubyflie
120
129
  when :switch_xmode
121
130
  @xmode = !@xmode if value > 0
122
131
  logger.info("Xmode is #{@xmode}") if value > 0
132
+ when :switch_scaled_output_mode
133
+ if value > 0 && @output_scale == 0
134
+ logger.info("Scaling output: x#{value}")
135
+ @output_scale = value.to_f
136
+ elsif value > 0 && @output_scale > 0
137
+ logger.info("Scaling output disabled")
138
+ @output_scale = 0
139
+ end
123
140
  when :close_link
124
141
  crazyflie.close_link() if value > 0
125
142
  end
@@ -140,6 +157,11 @@ module Crubyflie
140
157
  end
141
158
  end
142
159
 
160
+ setpoint.keys().each do |k|
161
+ next if k == :thrust
162
+ setpoint[k] *= @output_scale
163
+ end if @output_scale > 0
164
+
143
165
  pitch = setpoint[:pitch]
144
166
  roll = setpoint[:roll]
145
167
  yaw = setpoint[:yaw]
@@ -41,6 +41,8 @@ module Crubyflie
41
41
  # Default configuration file
42
42
  DEFAULT_CONFIG_PATH = File.join(File.dirname(__FILE__), "..","..","..",
43
43
  "configs", "joystick_default.yaml")
44
+ THRUST_MAX = 60000
45
+ THRUST_MIN = 9500
44
46
 
45
47
  attr_reader :config, :joystick_index
46
48
  # Initializes the Joystick configuration and the SDL library
@@ -107,7 +109,14 @@ module Crubyflie
107
109
 
108
110
  # output value max jump per second. We covert to rate/ms
109
111
  max_chrate = axis_cfg[:max_change_rate] || 10000
110
- axis_cfg[:max_change_rate] = max_chrate.to_f / 1000
112
+ if action == :thrust
113
+ # Thrust expressed in %
114
+ w = THRUST_MAX - THRUST_MIN
115
+ max_chrate = (max_chrate.to_f * w /100) / 1000
116
+ else
117
+ max_chrate = max_chrate.to_f / 1000
118
+ end
119
+ axis_cfg[:max_change_rate] = max_chrate
111
120
 
112
121
  axis_cfg[:last_poll] ||= 0
113
122
  axis_cfg[:last_value] ||= 0
@@ -117,7 +126,7 @@ module Crubyflie
117
126
  end
118
127
 
119
128
  buttons = {}
120
- config_h[:buttons] = buttons if config_h[:buttons].nil?
129
+ config_h[:buttons] = {} if config_h[:buttons].nil?
121
130
 
122
131
  config_h[:buttons].each do |id, button_cfg|
123
132
  action = button_cfg[:action]
@@ -125,6 +134,7 @@ module Crubyflie
125
134
  raise JoystickException.new("Button #{id} needs an action")
126
135
  end
127
136
  buttons[id] = action
137
+ button_cfg[:value] ||= 1
128
138
  end
129
139
 
130
140
  @config = config_h
@@ -189,7 +199,13 @@ module Crubyflie
189
199
  # the dead zone
190
200
  if dead_zone[:start] < value && dead_zone[:end] > value
191
201
  value = 0
192
- elsif value > input_range[:end]
202
+ elsif dead_zone[:start] >= value
203
+ value = value - dead_zone[:start]
204
+ elsif dead_zone[:end] <= value
205
+ value = value - dead_zone[:end]
206
+ end
207
+
208
+ if value > input_range[:end]
193
209
  value = input_range[:end]
194
210
  elsif value < input_range[:start]
195
211
  value = input_range[:start]
@@ -206,7 +222,7 @@ module Crubyflie
206
222
  current_time = Time.now.to_f
207
223
  timespan = current_time - last_poll
208
224
  # How many ms have passed since last time
209
- timespan_ms = timespan.round(3) * 1000
225
+ timespan_ms = timespan * 1000
210
226
  # How much have we changed/ms
211
227
  change = (value - last_value) / timespan_ms.to_f
212
228
 
@@ -252,9 +268,9 @@ module Crubyflie
252
268
  }
253
269
 
254
270
  cf_range = {
255
- :start => 9500.0,
256
- :end => 60000.0,
257
- :width => 50500.0
271
+ :start => THRUST_MIN,
272
+ :end => THRUST_MAX,
273
+ :width => THRUST_MAX - THRUST_MIN
258
274
  }
259
275
  return normalize(value, range, cf_range).round
260
276
  end
@@ -269,17 +285,19 @@ module Crubyflie
269
285
  def read_button(button_id)
270
286
  return -1 if !@joystick
271
287
 
272
- last_poll = @config[:buttons][button_id][:last_poll] || 0
273
- last_value = @config[:buttons][button_id][:last_value] || -1
274
- value = @joystick.button(button_id) ? 1 : -1
288
+ button = @config[:buttons][button_id]
289
+ last_poll = button[:last_poll] || 0
290
+ last_value = button[:last_value] || -1
291
+ pressed = @joystick.button(button_id)
292
+ value_pressed = button[:value]
275
293
  current_time = Time.now.to_f
276
294
 
277
295
  if (current_time - last_poll) > 0.5
278
- @config[:buttons][button_id][:last_value] = value
279
- @config[:buttons][button_id][:last_poll] = current_time
280
- return value
296
+ button[:last_value] = value_pressed
297
+ button[:last_poll] = current_time
298
+ return pressed ? value_pressed : 0
281
299
  else
282
- return -1
300
+ return 0
283
301
  end
284
302
  end
285
303
  private :read_button
@@ -304,7 +322,7 @@ module Crubyflie
304
322
  from_w = from_range[:width]
305
323
  # puts "#{to_min}+(#{value.to_f}-#{from_min})*(#{to_w}/#{from_w})
306
324
  r = to_min + (value.to_f - from_min) * (to_w / from_w)
307
- return r.round(3)
325
+ return r.round(2)
308
326
  end
309
327
  end
310
328
  end
@@ -18,5 +18,5 @@
18
18
 
19
19
  module Crubyflie
20
20
  # Current gem version
21
- VERSION = "0.1.2"
21
+ VERSION = "0.1.3"
22
22
  end
@@ -56,8 +56,8 @@ describe InputReader do
56
56
  }
57
57
 
58
58
  @joystick.button_readings.should == {
59
- :switch_xmode => -1,
60
- :close_link => -1
59
+ :switch_xmode => 0,
60
+ :close_link => 0
61
61
  }
62
62
  end
63
63
  end
@@ -1,23 +1,21 @@
1
- # Default joystick configuration file. It mimics the PS3_Mode2 original
2
- # configuration file
3
1
  :type: "Joystick"
4
2
  :axis:
5
3
  0:
6
4
  :description: "Roll Axis"
7
5
  :action: :roll
8
- :input_range: "-32768:32767" # Optional - SDL dependant. Defaults to this.
9
- :output_range: "-30:30" # Min/Max crazyflie angle in degrees.
10
- :max_change_rate: 600 # Max angle change rate per second. Optional
11
- :dead_zone: "-100:100" # Deadzone, within input range
12
- :invert: false # Invert the axis
13
- :calibration: 0 # This value is added to the raw value read from joystick
6
+ :input_range: "-32768:32767"
7
+ :output_range: "-30:30"
8
+ :max_change_rate: 600
9
+ :dead_zone: "-100:100"
10
+ :invert: false
11
+ :calibration: 0
14
12
  1:
15
13
  :description: "Pitch Axis"
16
14
  :action: :pitch
17
15
  :input_range: "-32768:32767"
18
16
  :output_range: "-30:30"
19
- :max_change_rate: 600 # Max angle change rate per second. Optional
20
- :dead_zone: "-100:100" # Deadzone, within input range
17
+ :max_change_rate: 600
18
+ :dead_zone: "0:0"
21
19
  :invert: true
22
20
  :calibration: 0
23
21
  2:
@@ -33,11 +31,9 @@
33
31
  :description: "Thrust axis"
34
32
  :action: :thrust
35
33
  :input_range: "-32768:32767"
36
- :output_range: "0:80" # Min/max thrust output is represented in 0-100%
37
- # Max change rate per second when lowering thrust. Thrust level is
38
- # ranges 9500 and 60000
34
+ :output_range: "0:80"
39
35
  :max_change_rate: 40000
40
- :dead_zone: "-100:100" # Deadzone, within input range
36
+ :dead_zone: "-100:100"
41
37
  :invert: true
42
38
  :calibration: 0
43
39
 
@@ -233,7 +233,7 @@ describe Joystick do
233
233
  expect(@sdl_joystick).to receive(:axis).with(8).and_return(140)
234
234
  @joystick.read_configuration('baa')
235
235
  value = @joystick.read_axis(8)
236
- value.should == 34749.5
236
+ value.should == 34497.5
237
237
  end
238
238
 
239
239
  it "should not throotle the change rate when increasing thrust" do
@@ -317,7 +317,7 @@ describe Joystick do
317
317
  it "should return -1 when not pressed" do
318
318
  expect(@sdl_joystick).to receive(:button).and_return(false)
319
319
  v = @joystick.send(:read_button, 0)
320
- v.should == -1
320
+ v.should == 0
321
321
  end
322
322
  end
323
323
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crubyflie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hector Sanjuan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-11 00:00:00.000000000 Z
11
+ date: 2013-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libusb