nl-knd_client 0.0.0.pre.usegit → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +67 -0
- data/bin/ansi_art.rb +48 -0
- data/bin/grayscale.rb +41 -0
- data/ext/kinutils/kinutils.c +59 -15
- data/ext/kinutils/unpack.c +1 -27
- data/ext/kinutils/unpack.h +41 -0
- data/lib/nl/knd_client/em_knd_client.rb +1 -0
- data/lib/nl/knd_client/simple_knd_client.rb +14 -2
- data/lib/nl/knd_client/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 336ea86637ac621dac8b4b939b354ca30745f785af71d749c8409e899c0bdb28
|
4
|
+
data.tar.gz: aaba0d0150ef2e6853e6b8494e5d786222da06c7125b8adb09587ce800e7675c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9017fe526991a5e1b4011c3b1356988fa22f782b167acaca5067e7b06f709803e17aa090748b0eb7a2b848847574d63f0afe90d5476cbf8cd7ad1ef14e5198ec
|
7
|
+
data.tar.gz: 8b705db457836405b48de38e1ee89654d3afbe451988e26b2382c3343243686f5840098c3360b504b2b1b45b1a305872d8bb73d40a4b5472f95c04e6708a1c3b
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -43,6 +43,73 @@ $ bundle install
|
|
43
43
|
|
44
44
|
TODO: Write usage instructions here
|
45
45
|
|
46
|
+
### Quick and dirty ASCII/ANSI art
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
knd = NL::KndClient::SimpleKndClient.new
|
50
|
+
knd.open
|
51
|
+
|
52
|
+
d11 = knd.get_depth
|
53
|
+
d16 = NL::KndClient::Kinutils.unpack11_to_16_lut(d11)
|
54
|
+
|
55
|
+
knd.close
|
56
|
+
|
57
|
+
# img will contain full 3D coordinates after this, but we'll only use Z here.
|
58
|
+
# img[y][x] will return the voxel at (x, y) in the 640x480 data.
|
59
|
+
img = d16.unpack('S*').map { |v|
|
60
|
+
NL::KndClient::Kinutils::DEPTH_LUT[v]
|
61
|
+
}.each_slice(640).map.with_index { |row, y|
|
62
|
+
row.map.with_index { |zw, x|
|
63
|
+
if zw > 4000
|
64
|
+
{x: 0, y: 0, z: -1}
|
65
|
+
else
|
66
|
+
{
|
67
|
+
x: NL::KndClient::Kinutils.xworld(x, zw),
|
68
|
+
y: NL::KndClient::Kinutils.yworld(y, zw),
|
69
|
+
z: zw
|
70
|
+
}
|
71
|
+
end
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
puts img.each_slice(15).map(&:first).map { |z| z.each_slice(11).map(&:first) }.map { |z| z.map { |v| [0, v[:z] - 200].max / 450 } }.map { |z| z.map { |v| [".", '-', "\e[1m-\e[0m", 'o', "\e[1mo\e[0m", 'O', "\e[1mO\e[0m"].reverse[v] }.join }
|
76
|
+
```
|
77
|
+
|
78
|
+
```
|
79
|
+
-----------.......................---------------O--------O
|
80
|
+
-----------.....................--------------------------O
|
81
|
+
-----------.......OOOO.O........--------------------------O
|
82
|
+
-----O-----.......OOoooo........--------------------------O
|
83
|
+
-----------......OOOoooo.o......-OOoooo-------------------O
|
84
|
+
----O------......OOOOooooo.....OOoooooooo-----------------O
|
85
|
+
-----------.......OOoOooo......Oooooooooo-------------OOOOO
|
86
|
+
-----------.......OOOOOo.......Ooooooooo-------------OOOOOO
|
87
|
+
-----------........OOooo.......Ooooooooo-------------OOOOOO
|
88
|
+
-----------....--..OOooo........Oooooooo-------------OOOOOO
|
89
|
+
-----------...---...OOooo.......Ooooooo--------------OOOOOO
|
90
|
+
-----------...----..OOooo....Oooooooooo--------------OOOOOO
|
91
|
+
-----------.........OOooo.Oooooooooooooooooo---------OOOOOO
|
92
|
+
-----------.........OOooooOOoooooooooooooooooooo--OO-OOOOOO
|
93
|
+
-----------.........OOOoooooooooooooooooooooooooooooooOOOOO
|
94
|
+
-----------.........OOOooooooooooooooooooo-oo-oooooooooOOOO
|
95
|
+
-----------.........OOOooooooooooooooooooo--------OOOOOOOOO
|
96
|
+
-----------.---.O...OOOOooooOoooooooooooooo-----OOooOOOOOOO
|
97
|
+
----------------------------OOooooooooooooooo--OOOOOOOOOOOO
|
98
|
+
oo---------------------------OooooooooooooooOOOOOOOOOOOOOOO
|
99
|
+
ooo--------------------------OoooooooooooooOOOOOOOOOOOOOOOO
|
100
|
+
oooo--------------------------OooooooooOOOOOOOOOOOOOOOOOOOO
|
101
|
+
ooooo-----------------OOO-O--OOoooooooOOOOOOOOOOOOOOOOOOOOO
|
102
|
+
ooooo---------OO-oo-----O-----OooooOOOOOOOOOOOOOOOOOOOOOOOO
|
103
|
+
ooooo----OOOooooooo-----OOO--OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
104
|
+
oooOOOOooooooooooooo--O-OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
105
|
+
oOooooooooooooooooo---O-OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
106
|
+
oooooooooooooooo-----OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
107
|
+
oooooooooooooo----OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
108
|
+
ooooooooooo---OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
109
|
+
ooooooo-----OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
110
|
+
ooooo----OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
111
|
+
```
|
112
|
+
|
46
113
|
### Standalone command-line processing
|
47
114
|
|
48
115
|
There is a Makefile in the `ext/` directory that will build standalone tools
|
data/bin/ansi_art.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Quick and dirty demo of the SimpleKndClient that displays live depth data as
|
3
|
+
# ANSI art.
|
4
|
+
#
|
5
|
+
# (C)2020 Mike Bourgeous
|
6
|
+
|
7
|
+
require 'bundler/setup'
|
8
|
+
|
9
|
+
require 'nl/knd_client'
|
10
|
+
|
11
|
+
begin
|
12
|
+
knd = NL::KndClient::SimpleKndClient.new
|
13
|
+
knd.open
|
14
|
+
|
15
|
+
STDOUT.write "\e[H\e[J"
|
16
|
+
|
17
|
+
loop do
|
18
|
+
d11 = knd.get_depth
|
19
|
+
d16 = NL::KndClient::Kinutils.unpack11_to_16_lut(d11)
|
20
|
+
|
21
|
+
# img will contain full 3D coordinates after this, but we'll only use Z here.
|
22
|
+
# img[y][x] will return the voxel at (x, y) in the 640x480 data.
|
23
|
+
img = d16.unpack('S*').map { |v|
|
24
|
+
NL::KndClient::Kinutils::DEPTH_LUT[v]
|
25
|
+
}.each_slice(640).map.with_index { |row, y|
|
26
|
+
row.map.with_index { |zw, x|
|
27
|
+
if zw > 4000
|
28
|
+
{x: 0, y: 0, z: -1}
|
29
|
+
else
|
30
|
+
{
|
31
|
+
x: NL::KndClient::Kinutils.xworld(x, zw),
|
32
|
+
y: NL::KndClient::Kinutils.yworld(y, zw),
|
33
|
+
z: zw
|
34
|
+
}
|
35
|
+
end
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
charmap = [".", '-', "\e[1m-\e[0m", 'o', "\e[1mo\e[0m", 'O', "\e[1mO\e[0m"].reverse
|
40
|
+
|
41
|
+
puts img.each_slice(15).map(&:first).map { |z| z.each_slice(11).map(&:first) }.map { |z| z.map { |v| [0, v[:z] - 200].max / 450 } }.map { |z| z.map { |v| charmap[v] }.join }
|
42
|
+
|
43
|
+
STDOUT.write "\e[H"
|
44
|
+
end
|
45
|
+
ensure
|
46
|
+
knd&.close
|
47
|
+
puts "\e[45H\e[0m"
|
48
|
+
end
|
data/bin/grayscale.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Displays live depth data as a grayscale range using SimpleKndClient.
|
3
|
+
# Requires a truecolor-capable terminal.
|
4
|
+
#
|
5
|
+
# (C)2020 Mike Bourgeous
|
6
|
+
|
7
|
+
require 'bundler/setup'
|
8
|
+
|
9
|
+
require 'nl/knd_client'
|
10
|
+
|
11
|
+
begin
|
12
|
+
knd = NL::KndClient::SimpleKndClient.new
|
13
|
+
knd.open
|
14
|
+
|
15
|
+
STDOUT.write "\e[H\e[J"
|
16
|
+
|
17
|
+
loop do
|
18
|
+
d11 = knd.get_depth
|
19
|
+
d8 = NL::KndClient::Kinutils.plot_linear(NL::KndClient::Kinutils.unpack11_to_16(d11))
|
20
|
+
|
21
|
+
# img will contain full 3D coordinates after this, but we'll only use Z here.
|
22
|
+
# img[y][x] will return the voxel at (x, y) in the 640x480 data.
|
23
|
+
img = d8.bytes.each_slice(640).to_a
|
24
|
+
|
25
|
+
chars = img.each_slice(15).map(&:first).map { |z|
|
26
|
+
z.each_slice(11).map(&:first)
|
27
|
+
}.map { |z|
|
28
|
+
z.map { |v|
|
29
|
+
gray = [v - 150, 0].max * 2
|
30
|
+
"\e[0;37;48;2;#{gray};#{gray};#{gray}m "
|
31
|
+
}.join
|
32
|
+
}
|
33
|
+
|
34
|
+
puts chars
|
35
|
+
|
36
|
+
STDOUT.write "\e[H"
|
37
|
+
end
|
38
|
+
ensure
|
39
|
+
knd&.close
|
40
|
+
puts "\e[45H\e[0m"
|
41
|
+
end
|
data/ext/kinutils/kinutils.c
CHANGED
@@ -23,6 +23,7 @@ struct unpack_info {
|
|
23
23
|
const uint8_t *in;
|
24
24
|
uint16_t *out;
|
25
25
|
size_t len;
|
26
|
+
unsigned int lut_range:1;
|
26
27
|
};
|
27
28
|
|
28
29
|
struct kvp_info {
|
@@ -39,15 +40,21 @@ void *unpack_blocking(void *data)
|
|
39
40
|
struct unpack_info *info = data;
|
40
41
|
size_t i, o;
|
41
42
|
|
42
|
-
|
43
|
-
|
43
|
+
if (info->lut_range) {
|
44
|
+
for(i = 0, o = 0; i < info->len; i += 11, o += 8) {
|
45
|
+
unpack11_to_16_lut(info->in + i, info->out + o);
|
46
|
+
}
|
47
|
+
} else {
|
48
|
+
for(i = 0, o = 0; i < info->len; i += 11, o += 8) {
|
49
|
+
unpack11_to_16(info->in + i, info->out + o);
|
50
|
+
}
|
44
51
|
}
|
45
52
|
|
46
53
|
return NULL;
|
47
54
|
}
|
48
55
|
|
49
|
-
// Ruby function to unpack 11-bit depth data to 16-bit left-aligned values
|
50
|
-
VALUE
|
56
|
+
// Ruby function to unpack 11-bit depth data to 16-bit left-aligned or right-aligned values.
|
57
|
+
static VALUE internal_unpack11_to_16(int lut_range, VALUE data)
|
51
58
|
{
|
52
59
|
size_t len, newlen;
|
53
60
|
VALUE outbuf;
|
@@ -64,7 +71,7 @@ VALUE rb_unpack11_to_16(VALUE self, VALUE data)
|
|
64
71
|
|
65
72
|
rb_thread_call_without_gvl(
|
66
73
|
unpack_blocking,
|
67
|
-
&(struct unpack_info){.in = (uint8_t *)RSTRING_PTR(data), .out = (uint16_t *)RSTRING_PTR(outbuf), .len = len},
|
74
|
+
&(struct unpack_info){.in = (uint8_t *)RSTRING_PTR(data), .out = (uint16_t *)RSTRING_PTR(outbuf), .len = len, .lut_range = !!lut_range},
|
68
75
|
NULL,
|
69
76
|
NULL
|
70
77
|
);
|
@@ -72,11 +79,23 @@ VALUE rb_unpack11_to_16(VALUE self, VALUE data)
|
|
72
79
|
return outbuf;
|
73
80
|
}
|
74
81
|
|
75
|
-
|
82
|
+
// Unpacks to 16-bit left-aligned values (for presentation, or passing into plot_linear)
|
83
|
+
VALUE rb_unpack11_to_16(VALUE self, VALUE data)
|
84
|
+
{
|
85
|
+
return internal_unpack11_to_16(0, data);
|
86
|
+
}
|
87
|
+
|
88
|
+
// Unpacks to 16-bit right-aligned values (for direct use in DEPTH_LUT)
|
89
|
+
VALUE rb_unpack11_to_16_lut(VALUE self, VALUE data)
|
90
|
+
{
|
91
|
+
return internal_unpack11_to_16(1, data);
|
92
|
+
}
|
93
|
+
|
94
|
+
void *plot_linear_blocking(void *data)
|
76
95
|
{
|
77
96
|
struct plot_info *info = data;
|
78
97
|
plot_linear(info->in, info->out);
|
79
|
-
return
|
98
|
+
return NULL;
|
80
99
|
}
|
81
100
|
|
82
101
|
// Ruby function to plot perspective view of linear depth data. Input:
|
@@ -108,11 +127,11 @@ VALUE rb_plot_linear(VALUE self, VALUE data)
|
|
108
127
|
return outbuf;
|
109
128
|
}
|
110
129
|
|
111
|
-
|
130
|
+
void *plot_overhead_blocking(void *data)
|
112
131
|
{
|
113
132
|
struct plot_info *info = data;
|
114
133
|
plot_overhead(info->in, info->out);
|
115
|
-
return
|
134
|
+
return NULL;
|
116
135
|
}
|
117
136
|
|
118
137
|
// Ruby function to plot overhead view of depth data. Input: 640x480x16bit
|
@@ -144,11 +163,11 @@ VALUE rb_plot_overhead(VALUE self, VALUE data)
|
|
144
163
|
return outbuf;
|
145
164
|
}
|
146
165
|
|
147
|
-
|
166
|
+
void *plot_side_blocking(void *data)
|
148
167
|
{
|
149
168
|
struct plot_info *info = data;
|
150
169
|
plot_side(info->in, info->out);
|
151
|
-
return
|
170
|
+
return NULL;
|
152
171
|
}
|
153
172
|
|
154
173
|
// Ruby function to plot side view of depth data. Input: 640x480x16bit
|
@@ -181,11 +200,11 @@ VALUE rb_plot_side(VALUE self, VALUE data)
|
|
181
200
|
return outbuf;
|
182
201
|
}
|
183
202
|
|
184
|
-
|
203
|
+
void *plot_front_blocking(void *data)
|
185
204
|
{
|
186
205
|
struct plot_info *info = data;
|
187
206
|
plot_front(info->in, info->out);
|
188
|
-
return
|
207
|
+
return NULL;
|
189
208
|
}
|
190
209
|
|
191
210
|
// Ruby function to plot front view of depth data. Input: 640x480x16bit
|
@@ -366,6 +385,19 @@ VALUE rb_kvp(int argc, VALUE *argv, VALUE self)
|
|
366
385
|
return hash;
|
367
386
|
}
|
368
387
|
|
388
|
+
// Converts X in pixels 0..639 and Z in world-space millimeters from the sensor
|
389
|
+
// into horizontal world-space millimeters from the sensor centerline.
|
390
|
+
VALUE ext_xworld(VALUE self, VALUE xpix, VALUE zw)
|
391
|
+
{
|
392
|
+
return INT2FIX(ku_xworld(NUM2INT(xpix), NUM2INT(zw)));
|
393
|
+
}
|
394
|
+
|
395
|
+
// Converts Y in pixels 0..480 and Z in world-space millimeters from the sensor
|
396
|
+
// into vertical world-space millimeters from the sensor centerline.
|
397
|
+
VALUE ext_yworld(VALUE self, VALUE ypix, VALUE zw)
|
398
|
+
{
|
399
|
+
return INT2FIX(ku_yworld(NUM2INT(ypix), NUM2INT(zw)));
|
400
|
+
}
|
369
401
|
|
370
402
|
void Init_kinutils()
|
371
403
|
{
|
@@ -396,16 +428,28 @@ void Init_kinutils()
|
|
396
428
|
rb_define_global_const("ESCAPE_IF_QUOTED", INT2FIX(ESCAPE_IF_QUOTED));
|
397
429
|
|
398
430
|
rb_define_module_function(KinUtils, "unpack11_to_16", rb_unpack11_to_16, 1);
|
431
|
+
rb_define_module_function(KinUtils, "unpack11_to_16_lut", rb_unpack11_to_16_lut, 1);
|
399
432
|
rb_define_module_function(KinUtils, "plot_linear", rb_plot_linear, 1);
|
400
433
|
rb_define_module_function(KinUtils, "plot_overhead", rb_plot_overhead, 1);
|
401
434
|
rb_define_module_function(KinUtils, "plot_side", rb_plot_side, 1);
|
402
435
|
rb_define_module_function(KinUtils, "plot_front", rb_plot_front, 1);
|
403
436
|
|
404
|
-
// TODO: Move to a different extension
|
405
437
|
rb_define_method(rb_cString, "kin_unescape", rb_unescape, -1);
|
406
438
|
rb_define_method(rb_cString, "kin_unescape!", rb_unescape_modify, -1);
|
407
439
|
|
408
440
|
rb_define_method(rb_cString, "kin_kvp", rb_kvp, -1);
|
409
441
|
|
410
|
-
//
|
442
|
+
// 3D perspective projection
|
443
|
+
rb_define_module_function(KinUtils, "xworld", ext_xworld, 2);
|
444
|
+
rb_define_module_function(KinUtils, "yworld", ext_yworld, 2);
|
445
|
+
|
446
|
+
// Look-up table
|
447
|
+
VALUE lut_array = rb_ary_new2(2048);
|
448
|
+
for (int i = 0; i < 2048; i++) {
|
449
|
+
rb_ary_store(lut_array, i, INT2FIX(ku_depth_lut[i]));
|
450
|
+
}
|
451
|
+
rb_ary_freeze(lut_array);
|
452
|
+
rb_define_const(KinUtils, "DEPTH_LUT", lut_array);
|
453
|
+
|
454
|
+
// TODO: Add reverse_lut,unpack_to_world/unpack_to_8 functions
|
411
455
|
}
|
data/ext/kinutils/unpack.c
CHANGED
@@ -10,35 +10,9 @@
|
|
10
10
|
#define UNPACK_INLINE
|
11
11
|
#include "unpack.h"
|
12
12
|
|
13
|
-
// TODO: Put ku_xworld, ku_yworld, lut into a library of addons, or submit as patches
|
14
|
-
// to libfreenect.
|
15
|
-
|
16
13
|
// Depth look-up table (translates depth sample into world-space millimeters).
|
17
14
|
int ku_depth_lut[2048];
|
18
15
|
|
19
|
-
// Converts x in pixels and z in world millimeters to x in world millimeters.
|
20
|
-
static int ku_xworld(int x, int zw)
|
21
|
-
{
|
22
|
-
// tan 28 ~= .53171 (1089 ~= .53171 * 2048)
|
23
|
-
// 0xcccd is the ~reciprocal of 10 (factor of W/2=320)
|
24
|
-
// Add 2**34 (0x400000000) for rounding before shift
|
25
|
-
// Shift right by 35:
|
26
|
-
// 11 bits for tangent (* 2048 above)
|
27
|
-
// 19 bits for reciprocal multiplication by 1/10 (factor of W/2=320)
|
28
|
-
// 5 bits for division by 32 (other factor of W/2=320)
|
29
|
-
//
|
30
|
-
// In total, with an overly generous maximum range of +/-16384mm (15
|
31
|
-
// bits), and an overhead of 35 bits due to arithmetic, 50 bits are
|
32
|
-
// needed for the calculation.
|
33
|
-
return (((int64_t)zw * (320 - x) * 1089 * 0xcccd) + 0x400000000) >> 35;
|
34
|
-
}
|
35
|
-
|
36
|
-
// Converts y in pixels and z in world millimeters to y in world millimeters.
|
37
|
-
static int ku_yworld(int y, int zw)
|
38
|
-
{
|
39
|
-
return ku_xworld(y + (640 - 480) / 2, zw);
|
40
|
-
}
|
41
|
-
|
42
16
|
// Initializes the depth look-up table.
|
43
17
|
// Copied from the knd daemon code, based on:
|
44
18
|
// http://groups.google.com/group/openkinect/browse_thread/thread/31351846fd33c78/e98a94ac605b9f21#e98a94ac605b9f21
|
@@ -49,7 +23,7 @@ void ku_init_lut()
|
|
49
23
|
for(i = 0; i < 2047; i++) {
|
50
24
|
ku_depth_lut[i] = (int)(0.1236f * tanf(i / 2842.5f + 1.1863f) * 1000.0f);
|
51
25
|
}
|
52
|
-
ku_depth_lut[2047] = 1048576;
|
26
|
+
ku_depth_lut[2047] = 1048576; // 2047 is returned by the sensor for shadowed or undetectable pixels
|
53
27
|
}
|
54
28
|
|
55
29
|
// Finds the closest entry in the depth look-up table to the given world-space
|
data/ext/kinutils/unpack.h
CHANGED
@@ -25,8 +25,26 @@
|
|
25
25
|
// Depth look-up table (translates depth sample into world-space millimeters).
|
26
26
|
extern int ku_depth_lut[2048];
|
27
27
|
|
28
|
+
// Unpacks and inverts 8 11-bit pixels (11 bytes) from in and stores them as
|
29
|
+
// LSB-aligned 16-bit values in out (16 bytes), which can be used directly as
|
30
|
+
// indices in ku_depth_lut.
|
31
|
+
UNPACK_INLINE void unpack11_to_16_lut(const uint8_t *in, uint16_t *out)
|
32
|
+
{
|
33
|
+
out[0] = ((in[0] << 3) | (in[1] >> 5));
|
34
|
+
out[1] = (((in[1] & 0x1f) << 6) | (in[2] >> 2));
|
35
|
+
out[2] = (((in[2] & 0x03) << 9) | (in[3] << 1) | (in[4] >> 7));
|
36
|
+
out[3] = (((in[4] & 0x7f) << 4) | (in[5] >> 4));
|
37
|
+
out[4] = (((in[5] & 0x0f) << 7) | (in[6] >> 1));
|
38
|
+
out[5] = (((in[6] & 0x01) << 10) | (in[7] << 2) | (in[8] >> 6));
|
39
|
+
out[6] = (((in[8] & 0x3f) << 5) | (in[9] >> 3));
|
40
|
+
out[7] = (((in[9] & 0x07) << 8) | in[10]);
|
41
|
+
}
|
42
|
+
|
28
43
|
// Unpacks and inverts 8 11-bit pixels (11 bytes) from in and stores them as
|
29
44
|
// MSB-aligned 16-bit values in out (16 bytes)
|
45
|
+
//
|
46
|
+
// The range is scaled and inverted to look presentable in a 16-bit sRGB PNG
|
47
|
+
// image. To convert back to LUT indices
|
30
48
|
UNPACK_INLINE void unpack11_to_16(const uint8_t *in, uint16_t *out)
|
31
49
|
{
|
32
50
|
out[0] = 65535 - (((in[0] << 3) | (in[1] >> 5)) << 5);
|
@@ -80,6 +98,29 @@ UNPACK_INLINE int pxval_11(uint8_t *buf, int pixel)
|
|
80
98
|
return (base >> shiftbits) & 0x7ff;
|
81
99
|
}
|
82
100
|
|
101
|
+
// Converts x in pixels and z in world millimeters to x in world millimeters.
|
102
|
+
UNPACK_INLINE int ku_xworld(int x, int zw)
|
103
|
+
{
|
104
|
+
// tan 28 ~= .53171 (1089 ~= .53171 * 2048)
|
105
|
+
// 0xcccd is the ~reciprocal of 10 (factor of W/2=320)
|
106
|
+
// Add 2**34 (0x400000000) for rounding before shift
|
107
|
+
// Shift right by 35:
|
108
|
+
// 11 bits for tangent (* 2048 above)
|
109
|
+
// 19 bits for reciprocal multiplication by 1/10 (factor of W/2=320)
|
110
|
+
// 5 bits for division by 32 (other factor of W/2=320)
|
111
|
+
//
|
112
|
+
// In total, with an overly generous maximum range of +/-16384mm (15
|
113
|
+
// bits), and an overhead of 35 bits due to arithmetic, 50 bits are
|
114
|
+
// needed for the calculation.
|
115
|
+
return (((int64_t)zw * (320 - x) * 1089 * 0xcccd) + 0x400000000) >> 35;
|
116
|
+
}
|
117
|
+
|
118
|
+
// Converts y in pixels and z in world millimeters to y in world millimeters.
|
119
|
+
UNPACK_INLINE int ku_yworld(int y, int zw)
|
120
|
+
{
|
121
|
+
return ku_xworld(y + (640 - 480) / 2, zw);
|
122
|
+
}
|
123
|
+
|
83
124
|
// Initializes the depth look-up table.
|
84
125
|
// Copied from the knd daemon code, based on:
|
85
126
|
// http://groups.google.com/group/openkinect/browse_thread/thread/31351846fd33c78/e98a94ac605b9f21#e98a94ac605b9f21
|
@@ -46,6 +46,19 @@ module NL
|
|
46
46
|
@socket = nil
|
47
47
|
end
|
48
48
|
|
49
|
+
# Sends the getdepth command to KND to request async delivery of a single
|
50
|
+
# depth frame.
|
51
|
+
def request_depth
|
52
|
+
@socket.puts('getdepth')
|
53
|
+
end
|
54
|
+
|
55
|
+
# Sends the subdepth command to KND to request continuous async delivery
|
56
|
+
# of depth frames. The optional +count+ will cause only that number of
|
57
|
+
# frames to be delivered.
|
58
|
+
def subscribe_depth(count = nil)
|
59
|
+
@socket.puts("subdepth#{count && " #{count}"}")
|
60
|
+
end
|
61
|
+
|
49
62
|
# Waits for and then returns depth data.
|
50
63
|
def get_depth
|
51
64
|
data = nil
|
@@ -54,7 +67,7 @@ module NL
|
|
54
67
|
cb = ->(d) { data = d; t.wakeup }
|
55
68
|
on_zone('! DEPTH', &cb)
|
56
69
|
|
57
|
-
|
70
|
+
request_depth
|
58
71
|
sleep(1)
|
59
72
|
|
60
73
|
raise "Data wasn't set within 1 second" if data.nil?
|
@@ -79,7 +92,6 @@ module NL
|
|
79
92
|
|
80
93
|
when 'DEPTH'
|
81
94
|
num_bytes = line.gsub(/\A[^0-9]*(\d+)[^0-9]*\z/, '\1').to_i
|
82
|
-
puts "\n\n\n\n\e[1;33m=========== DEPTH line #{num_bytes} ============\n\n\n\n"
|
83
95
|
data = @socket.read(num_bytes)
|
84
96
|
@callbacks['! DEPTH']&.each do |cb|
|
85
97
|
cb.call(data) rescue puts "Error calling depth callback: #{MB::Sound::U.syntax($!.inspect)}"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nl-knd_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Bourgeous
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nl-fast_png
|
@@ -95,7 +95,9 @@ files:
|
|
95
95
|
- LICENSE
|
96
96
|
- README.md
|
97
97
|
- Rakefile
|
98
|
+
- bin/ansi_art.rb
|
98
99
|
- bin/console
|
100
|
+
- bin/grayscale.rb
|
99
101
|
- bin/setup
|
100
102
|
- ext/Makefile
|
101
103
|
- ext/front.c
|
@@ -133,9 +135,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
135
|
version: 2.3.0
|
134
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
137
|
requirements:
|
136
|
-
- - "
|
138
|
+
- - ">="
|
137
139
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
140
|
+
version: '0'
|
139
141
|
requirements: []
|
140
142
|
rubygems_version: 3.1.4
|
141
143
|
signing_key:
|