gps_pvt 0.8.1 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -7
- data/exe/gps_pvt +1 -1
- data/exe/to_ubx +92 -29
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +398 -187
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +5 -3
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +5 -3
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_MultiFrequency.h +1 -0
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +5 -3
- data/ext/ninja-scan-light/tool/swig/GPS.i +54 -8
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +7 -0
- data/lib/gps_pvt/receiver/extension.rb +16 -7
- data/lib/gps_pvt/receiver.rb +38 -26
- data/lib/gps_pvt/version.rb +1 -1
- metadata +2 -2
@@ -57,13 +57,15 @@ struct GLONASS_SinglePositioning_Options : public GPS_Solver_GeneralOptions<Floa
|
|
57
57
|
|
58
58
|
template <class FloatT, class SolverBaseT = GPS_Solver_Base<FloatT> >
|
59
59
|
class GLONASS_SinglePositioning : public SolverBaseT {
|
60
|
-
private:
|
61
|
-
GLONASS_SinglePositioning<FloatT> &operator=(const GLONASS_SinglePositioning<FloatT> &);
|
62
60
|
public:
|
63
|
-
typedef GLONASS_SinglePositioning<FloatT> self_t;
|
61
|
+
typedef GLONASS_SinglePositioning<FloatT, SolverBaseT> self_t;
|
64
62
|
typedef SolverBaseT base_t;
|
65
63
|
typedef SolverBaseT super_t;
|
64
|
+
private:
|
65
|
+
self_t &operator=(const self_t &);
|
66
|
+
GLONASS_SinglePositioning(const self_t &);
|
66
67
|
|
68
|
+
public:
|
67
69
|
#if defined(__GNUC__) && (__GNUC__ < 5)
|
68
70
|
#define inheritate_type(x) typedef typename base_t::x x;
|
69
71
|
#else
|
@@ -77,12 +77,14 @@ struct GPS_SinglePositioning_Options : public GPS_Solver_GeneralOptions<FloatT>
|
|
77
77
|
|
78
78
|
template <class FloatT, class SolverBaseT = GPS_Solver_Base<FloatT> >
|
79
79
|
class GPS_SinglePositioning : public SolverBaseT {
|
80
|
-
private:
|
81
|
-
GPS_SinglePositioning<FloatT> &operator=(const GPS_SinglePositioning<FloatT> &);
|
82
80
|
public:
|
83
|
-
typedef GPS_SinglePositioning<FloatT> self_t;
|
81
|
+
typedef GPS_SinglePositioning<FloatT, SolverBaseT> self_t;
|
84
82
|
typedef SolverBaseT base_t;
|
83
|
+
private:
|
84
|
+
self_t &operator=(const self_t &);
|
85
|
+
GPS_SinglePositioning(const self_t &);
|
85
86
|
|
87
|
+
public:
|
86
88
|
#if defined(__GNUC__) && (__GNUC__ < 5)
|
87
89
|
#define inheritate_type(x) typedef typename base_t::x x;
|
88
90
|
#else
|
@@ -52,6 +52,7 @@ class GPS_Solver_MultiFrequency : public BaseSolver {
|
|
52
52
|
typedef BaseSolver super_t;
|
53
53
|
private:
|
54
54
|
self_t &operator=(const self_t &);
|
55
|
+
GPS_Solver_MultiFrequency(const self_t &);
|
55
56
|
public:
|
56
57
|
#if defined(__GNUC__) && (__GNUC__ < 5)
|
57
58
|
#define inheritate_type(x) typedef typename super_t::x x;
|
@@ -56,12 +56,14 @@ struct SBAS_SinglePositioning_Options : public GPS_Solver_GeneralOptions<FloatT>
|
|
56
56
|
|
57
57
|
template <class FloatT, class SolverBaseT = GPS_Solver_Base<FloatT> >
|
58
58
|
class SBAS_SinglePositioning : public SolverBaseT {
|
59
|
-
private:
|
60
|
-
SBAS_SinglePositioning<FloatT> &operator=(const SBAS_SinglePositioning<FloatT> &);
|
61
59
|
public:
|
62
|
-
typedef SBAS_SinglePositioning<FloatT> self_t;
|
60
|
+
typedef SBAS_SinglePositioning<FloatT, SolverBaseT> self_t;
|
63
61
|
typedef SolverBaseT base_t;
|
62
|
+
private:
|
63
|
+
self_t &operator=(const self_t &);
|
64
|
+
SBAS_SinglePositioning(const self_t &);
|
64
65
|
|
66
|
+
public:
|
65
67
|
#if defined(__GNUC__) && (__GNUC__ < 5)
|
66
68
|
#define inheritate_type(x) typedef typename base_t::x x;
|
67
69
|
#else
|
@@ -29,6 +29,7 @@
|
|
29
29
|
#include "navigation/GPS_Solver_Base.h"
|
30
30
|
#include "navigation/GPS_Solver.h"
|
31
31
|
#include "navigation/GPS_Solver_RAIM.h"
|
32
|
+
#include "navigation/GPS_Solver_MultiFrequency.h"
|
32
33
|
#include "navigation/SBAS_Solver.h"
|
33
34
|
#include "navigation/GLONASS_Solver.h"
|
34
35
|
|
@@ -157,6 +158,16 @@ static std::string inspect_str(const VALUE &v){
|
|
157
158
|
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) const std::tm & {
|
158
159
|
$1 = (TYPE($input) == T_ARRAY) ? 1 : 0;
|
159
160
|
}
|
161
|
+
%typemap(varout,fragment="SWIG_Traits_frag(FloatT)") leap_second_event_t [] {
|
162
|
+
$result = rb_ary_new2(sizeof($1) / sizeof($1[0]));
|
163
|
+
for(std::size_t i(0); i < sizeof($1) / sizeof($1[0]); ++i){
|
164
|
+
rb_ary_push($result,
|
165
|
+
rb_ary_new3(3,
|
166
|
+
SWIG_From(int)($1[i].corrected.week),
|
167
|
+
swig::from($1[i].corrected.seconds),
|
168
|
+
SWIG_From(int)($1[i].leap_seconds)));
|
169
|
+
}
|
170
|
+
}
|
160
171
|
#endif
|
161
172
|
%ignore canonicalize();
|
162
173
|
%ignore GPS_Time(const int &_week, const float_t &_seconds);
|
@@ -1119,6 +1130,16 @@ struct GPS_Measurement {
|
|
1119
1130
|
L1_SIGNAL_STRENGTH_dBHz,
|
1120
1131
|
L1_LOCK_SEC,
|
1121
1132
|
L1_FREQUENCY,
|
1133
|
+
#define make_entry(key) L2CM_ ## key, L2CL_ ## key
|
1134
|
+
#define make_entry2(key) make_entry(key), make_entry(key ## _SIGMA)
|
1135
|
+
make_entry2(PSEUDORANGE),
|
1136
|
+
make_entry2(CARRIER_PHASE),
|
1137
|
+
make_entry2(DOPPLER),
|
1138
|
+
make_entry2(RANGE_RATE),
|
1139
|
+
make_entry(SIGNAL_STRENGTH_dBHz),
|
1140
|
+
make_entry(LOCK_SEC),
|
1141
|
+
#undef make_entry2
|
1142
|
+
#undef make_entry
|
1122
1143
|
ITEMS_PREDEFINED,
|
1123
1144
|
};
|
1124
1145
|
void add(const int &prn, const int &key, const FloatT &value){
|
@@ -1142,7 +1163,7 @@ const type &get_ ## name () const {
|
|
1142
1163
|
MAKE_ACCESSOR2(residual_mask, FloatT);
|
1143
1164
|
#undef MAKE_ACCESSOR2
|
1144
1165
|
MAKE_VECTOR2ARRAY(int);
|
1145
|
-
%ignore
|
1166
|
+
%ignore cast_general;
|
1146
1167
|
}
|
1147
1168
|
%inline %{
|
1148
1169
|
template <class FloatT>
|
@@ -1156,17 +1177,23 @@ struct GPS_SolverOptions_Common {
|
|
1156
1177
|
%extend GPS_SolverOptions {
|
1157
1178
|
%ignore base_t;
|
1158
1179
|
%ignore cast_general;
|
1180
|
+
#ifdef SWIGRUBY
|
1181
|
+
%rename("exclude_L2C?") get_exclude_L2C;
|
1182
|
+
%rename("exclude_L2C=") set_exclude_L2C;
|
1183
|
+
#endif
|
1159
1184
|
MAKE_VECTOR2ARRAY(int);
|
1160
1185
|
}
|
1161
1186
|
%inline %{
|
1162
1187
|
template <class FloatT>
|
1163
1188
|
struct GPS_SolverOptions
|
1164
|
-
: public GPS_SinglePositioning<FloatT>::options_t,
|
1189
|
+
: public GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >::options_t,
|
1165
1190
|
GPS_SolverOptions_Common<FloatT> {
|
1166
|
-
typedef typename GPS_SinglePositioning<FloatT>::options_t base_t;
|
1191
|
+
typedef typename GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >::options_t base_t;
|
1167
1192
|
void exclude(const int &prn){base_t::exclude_prn.set(prn);}
|
1168
1193
|
void include(const int &prn){base_t::exclude_prn.reset(prn);}
|
1169
1194
|
std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
|
1195
|
+
bool get_exclude_L2C() {return base_t::exclude_L2C;}
|
1196
|
+
bool set_exclude_L2C(const bool &b) {return base_t::exclude_L2C = b;}
|
1170
1197
|
GPS_Solver_GeneralOptions<FloatT> *cast_general(){return this;}
|
1171
1198
|
const GPS_Solver_GeneralOptions<FloatT> *cast_general() const {return this;}
|
1172
1199
|
};
|
@@ -1236,7 +1263,8 @@ template <class BaseT, class HookT>
|
|
1236
1263
|
struct HookableSolver : public BaseT {
|
1237
1264
|
typedef BaseT base_t;
|
1238
1265
|
HookT *hook;
|
1239
|
-
|
1266
|
+
template <class ArgT>
|
1267
|
+
HookableSolver(const ArgT &);
|
1240
1268
|
virtual typename base_t::relative_property_t relative_property(
|
1241
1269
|
const typename base_t::prn_t &prn,
|
1242
1270
|
const typename base_t::measurement_t::mapped_type &measurement,
|
@@ -1289,6 +1317,20 @@ struct HookableSolver : public BaseT {
|
|
1289
1317
|
fragment=SWIG_From_frag(int),
|
1290
1318
|
fragment=SWIG_Traits_frag(FloatT),
|
1291
1319
|
fragment=SWIG_Traits_frag(GPS_Measurement<FloatT>)){
|
1320
|
+
template <> template <>
|
1321
|
+
HookableSolver<
|
1322
|
+
GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >,
|
1323
|
+
GPS_Solver<FloatT> >
|
1324
|
+
::HookableSolver<GPS_SpaceNode<FloatT> >(const GPS_SpaceNode<FloatT> &sn)
|
1325
|
+
: GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >(sn), hook(NULL) {}
|
1326
|
+
template <> template <>
|
1327
|
+
HookableSolver<SBAS_SinglePositioning<FloatT>, GPS_Solver<FloatT> >
|
1328
|
+
::HookableSolver<SBAS_SpaceNode<FloatT> >(const SBAS_SpaceNode<FloatT> &sn)
|
1329
|
+
: SBAS_SinglePositioning<FloatT>(sn), hook(NULL) {}
|
1330
|
+
template <> template <>
|
1331
|
+
HookableSolver<GLONASS_SinglePositioning<FloatT>, GPS_Solver<FloatT> >
|
1332
|
+
::HookableSolver<GLONASS_SpaceNode<FloatT> >(const GLONASS_SpaceNode<FloatT> &sn)
|
1333
|
+
: GLONASS_SinglePositioning<FloatT>(sn), hook(NULL) {}
|
1292
1334
|
template <>
|
1293
1335
|
GPS_Solver<FloatT>::base_t::relative_property_t
|
1294
1336
|
GPS_Solver<FloatT>::relative_property(
|
@@ -1581,7 +1623,9 @@ struct GPS_Solver
|
|
1581
1623
|
struct gps_t {
|
1582
1624
|
GPS_SpaceNode<FloatT> space_node;
|
1583
1625
|
GPS_SolverOptions<FloatT> options;
|
1584
|
-
HookableSolver<
|
1626
|
+
HookableSolver<
|
1627
|
+
GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >,
|
1628
|
+
GPS_Solver<FloatT> > solver;
|
1585
1629
|
struct ephemeris_proxy_t {
|
1586
1630
|
struct item_t {
|
1587
1631
|
const void *impl;
|
@@ -1603,19 +1647,21 @@ struct GPS_Solver
|
|
1603
1647
|
solver.satellites.impl_select = forward;
|
1604
1648
|
}
|
1605
1649
|
} ephemeris_proxy;
|
1606
|
-
gps_t() : space_node(), options(), solver(
|
1650
|
+
gps_t() : space_node(), options(), solver(space_node), ephemeris_proxy(solver) {
|
1651
|
+
options.exclude_L2C = true;
|
1652
|
+
}
|
1607
1653
|
} gps;
|
1608
1654
|
struct sbas_t {
|
1609
1655
|
SBAS_SpaceNode<FloatT> space_node;
|
1610
1656
|
SBAS_SolverOptions<FloatT> options;
|
1611
1657
|
HookableSolver<SBAS_SinglePositioning<FloatT>, GPS_Solver<FloatT> > solver;
|
1612
|
-
sbas_t() : space_node(), options(), solver(
|
1658
|
+
sbas_t() : space_node(), options(), solver(space_node) {}
|
1613
1659
|
} sbas;
|
1614
1660
|
struct glonass_t {
|
1615
1661
|
GLONASS_SpaceNode<FloatT> space_node;
|
1616
1662
|
GLONASS_SolverOptions<FloatT> options;
|
1617
1663
|
HookableSolver<GLONASS_SinglePositioning<FloatT>, GPS_Solver<FloatT> > solver;
|
1618
|
-
glonass_t() : space_node(), options(), solver(
|
1664
|
+
glonass_t() : space_node(), options(), solver(space_node) {}
|
1619
1665
|
} glonass;
|
1620
1666
|
SWIG_Object hooks;
|
1621
1667
|
typedef std::vector<GPS_RangeCorrector<FloatT> > user_correctors_t;
|
@@ -759,6 +759,10 @@ __RINEX_CLK_TEXT__
|
|
759
759
|
puts "Measurement time: #{t_meas.to_a} (a.k.a #{"%d/%d/%d %02d:%02d:%02d UTC"%[*t_meas.c_tm]})"
|
760
760
|
expect(t_meas.c_tm).to eq([2015, 6, 15, 23, 53, 33])
|
761
761
|
expect(GPS::Time::new(0, t_meas.serialize)).to eq(t_meas)
|
762
|
+
expect(t_meas.leap_seconds).to eq(sn.iono_utc.delta_t_LS)
|
763
|
+
expect(GPS::Time::leap_second_events.select{|wn, sec, leap|
|
764
|
+
t_meas >= GPS::Time::new(wn, sec)
|
765
|
+
}[0][2]).to eq(sn.iono_utc.delta_t_LS)
|
762
766
|
|
763
767
|
sn.update_all_ephemeris(t_meas)
|
764
768
|
|
@@ -924,6 +928,9 @@ __RINEX_CLK_TEXT__
|
|
924
928
|
}}.not_to raise_error
|
925
929
|
expect(solver.correction[:gps_ionospheric]).to include(:no_correction)
|
926
930
|
expect(solver.correction[:options][:f_10_7]).to eq(10)
|
931
|
+
expect(solver.gps_options.exclude_L2C?).to eq(true) #default
|
932
|
+
solver.gps_options.exclude_L2C = false
|
933
|
+
expect(solver.gps_options.exclude_L2C?).to eq(false)
|
927
934
|
sn.read(input[:rinex_nav])
|
928
935
|
t_meas = GPS::Time::new(1849, 172413)
|
929
936
|
sn.update_all_ephemeris(t_meas)
|
@@ -29,15 +29,24 @@ class Receiver
|
|
29
29
|
return (eph.valid?(t) ? eph : nil)
|
30
30
|
end
|
31
31
|
|
32
|
-
def attach_online_ephemeris(uri_template = nil)
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
def attach_online_ephemeris(uri_template = [nil])
|
33
|
+
uri_template = uri_template.collect{|v|
|
34
|
+
if (!v) || (v =~ /^\s*$/) then
|
35
|
+
"ftp://gssc.esa.int/gnss/data/daily/%Y/brdc/BRDC00IGS_R_%Y%j0000_01D_MN.rnx.gz"
|
36
|
+
else
|
37
|
+
v
|
38
|
+
end
|
39
|
+
}.uniq
|
36
40
|
loader = proc{|t_meas|
|
37
41
|
utc = Time::utc(*t_meas.c_tm)
|
38
|
-
|
39
|
-
|
40
|
-
|
42
|
+
uri_template.each{|v|
|
43
|
+
uri = URI::parse(utc.strftime(v))
|
44
|
+
begin
|
45
|
+
self.parse_rinex_nav(uri)
|
46
|
+
rescue Net::FTPError, Net::HTTPExceptions => e
|
47
|
+
$stderr.puts "Skip to read due to %s (%s)"%[e.inspect.gsub(/[\r\n]/, ' '), uri]
|
48
|
+
end
|
49
|
+
}
|
41
50
|
}
|
42
51
|
run_orig = self.method(:run)
|
43
52
|
eph_list = {}
|
data/lib/gps_pvt/receiver.rb
CHANGED
@@ -290,6 +290,11 @@ class Receiver
|
|
290
290
|
when :fault_exclusion
|
291
291
|
@solver.options = {:skip_exclusion => !(output_options[:FDE] = v.to_b)}
|
292
292
|
next true
|
293
|
+
when :use_signal
|
294
|
+
{
|
295
|
+
:GPS_L2C => proc{@solver.gps_options.exclude_L2C = false},
|
296
|
+
}[v.to_sym].call rescue next false
|
297
|
+
next true
|
293
298
|
end
|
294
299
|
false
|
295
300
|
}
|
@@ -334,9 +339,9 @@ class Receiver
|
|
334
339
|
}.flatten(1))]
|
335
340
|
}
|
336
341
|
}.call
|
337
|
-
|
342
|
+
add_orig = instance_method(:add)
|
338
343
|
define_method(:add){|prn, key, value|
|
339
|
-
add_orig(prn, key.kind_of?(Symbol) ? GPS::Measurement.const_get(key) : key, value)
|
344
|
+
add_orig.bind(self).call(prn, key.kind_of?(Symbol) ? GPS::Measurement.const_get(key) : key, value)
|
340
345
|
}
|
341
346
|
}
|
342
347
|
|
@@ -523,33 +528,39 @@ class Receiver
|
|
523
528
|
v
|
524
529
|
}
|
525
530
|
sys, svid = gnss_serial.call(*loader.call(36, 2).reverse)
|
526
|
-
|
527
|
-
next if (packet[6 + 13] != 0) && (loader.call(38, 1, "C") != 0)
|
531
|
+
sigid = (packet[6 + 13] != 0) ? loader.call(38, 1, "C") : 0 # sigID if version(>0); @see UBX-18010854
|
528
532
|
case sys
|
529
|
-
when :GPS
|
533
|
+
when :GPS
|
534
|
+
sigid = {0 => :L1, 3 => :L2CL, 4 => :L2CM}[sigid]
|
535
|
+
when :SBAS
|
536
|
+
sigid = :L1
|
537
|
+
when :QZSS
|
538
|
+
sigid = {0 => :L1, 5 => :L2CL, 4 => :L2CM}[sigid]
|
530
539
|
when :GLONASS
|
531
540
|
svid += 0x100
|
541
|
+
sigid = {0 => :L1}[sigid] # TODO: to support {2 -> :L2}
|
532
542
|
meas.add(svid, :L1_FREQUENCY,
|
533
543
|
GPS::SpaceNode_GLONASS::L1_frequency(loader.call(39, 1, "C") - 7))
|
534
544
|
else; next
|
535
545
|
end
|
546
|
+
next unless sigid
|
536
547
|
trk_stat = loader.call(46, 1)[0]
|
537
548
|
{
|
538
|
-
:
|
539
|
-
:
|
549
|
+
:PSEUDORANGE => [16, 8, "E", proc{|v| (trk_stat & 0x1 == 0x1) ? v : nil}],
|
550
|
+
:PSEUDORANGE_SIGMA => [43, 1, nil, proc{|v|
|
540
551
|
(trk_stat & 0x1 == 0x1) ? (1E-2 * (1 << (v[0] & 0xF))) : nil
|
541
552
|
}],
|
542
|
-
:
|
543
|
-
:
|
544
|
-
:
|
545
|
-
:
|
553
|
+
:DOPPLER => [32, 4, "e"],
|
554
|
+
:DOPPLER_SIGMA => [45, 1, nil, proc{|v| 2E-3 * (1 << (v[0] & 0xF))}],
|
555
|
+
:CARRIER_PHASE => [24, 8, "E", proc{|v| (trk_stat & 0x2 == 0x2) ? v : nil}],
|
556
|
+
:CARRIER_PHASE_SIGMA => [44, 1, nil, proc{|v|
|
546
557
|
(trk_stat & 0x2 == 0x2) ? (0.004 * (v[0] & 0xF)) : nil
|
547
558
|
}],
|
548
|
-
:
|
549
|
-
:
|
559
|
+
:SIGNAL_STRENGTH_dBHz => [42, 1, "C"],
|
560
|
+
:LOCK_SEC => [40, 2, "v", proc{|v| 1E-3 * v}],
|
550
561
|
}.each{|k, prop|
|
551
562
|
next unless v = loader.call(*prop)
|
552
|
-
meas.add(svid, k, v)
|
563
|
+
meas.add(svid, "#{sigid}_#{k}".to_sym, v) rescue nil # unsupported signal
|
553
564
|
}
|
554
565
|
}
|
555
566
|
after_run.call(run(meas, t_meas), [meas, t_meas])
|
@@ -605,18 +616,19 @@ class Receiver
|
|
605
616
|
|
606
617
|
types ||= Hash[*(item[:meas_types].collect{|sys, values|
|
607
618
|
[sys, values.collect.with_index{|type_, i|
|
608
|
-
case type_
|
609
|
-
|
610
|
-
[
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
619
|
+
sig_obs_type = [case type_[1..-1]
|
620
|
+
when /^1C?$/; :L1
|
621
|
+
when /^2[XL]$/; :L2CL
|
622
|
+
when /^2S$/; :L2CM
|
623
|
+
else; nil
|
624
|
+
end, {
|
625
|
+
'C' => :PSEUDORANGE,
|
626
|
+
'L' => :CARRIER_PHASE,
|
627
|
+
'D' => :DOPPLER,
|
628
|
+
'S' => :SIGNAL_STRENGTH_dBHz,
|
629
|
+
}[type_[0]]]
|
630
|
+
next nil unless sig_obs_type.all?
|
631
|
+
[i, sig_obs_type.join('_').to_sym]
|
620
632
|
}.compact]
|
621
633
|
}.flatten(1))]
|
622
634
|
|
data/lib/gps_pvt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gps_pvt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fenrir(M.Naruoka)
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyserial
|