rotctl: do range validation
This is at the interface layer though it should arguably be done at the controller layer. Oh well.
This commit is contained in:
parent
7105775426
commit
7fbfe1c5f7
@ -37,6 +37,15 @@ rotctl: RotControlConfig = .{
|
|||||||
labjack: LabjackConfig = .{
|
labjack: LabjackConfig = .{
|
||||||
.device = .autodetect,
|
.device = .autodetect,
|
||||||
.feedback_calibration = .{
|
.feedback_calibration = .{
|
||||||
|
// NOTE: these min and max angles are treated as hardware limits. This serves
|
||||||
|
// two purposes: first, it means that feedback is always interpolated,
|
||||||
|
// never extrapolated (though with a two point calibration, that doesn't
|
||||||
|
// matter much). Second, it prevents having a redundant set of bounds
|
||||||
|
// values that could potentially desync from these and cause problems.
|
||||||
|
//
|
||||||
|
// The functional min and max are these plus the angle offset values. For
|
||||||
|
// example, given controller.angle_offset.azimuth = -6, the practical minimum
|
||||||
|
// azimuth would be -6 deg and the practical maximum would be 444 deg.
|
||||||
.azimuth = .{
|
.azimuth = .{
|
||||||
.minimum = .{ .voltage = 0.0, .angle = 0.0 },
|
.minimum = .{ .voltage = 0.0, .angle = 0.0 },
|
||||||
.maximum = .{ .voltage = 5.0, .angle = 450.0 },
|
.maximum = .{ .voltage = 5.0, .angle = 450.0 },
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const config = @import("./Config.zig").global;
|
const Config = @import("./Config.zig");
|
||||||
|
const config = Config.global;
|
||||||
const LabjackYaesu = @import("./LabjackYaesu.zig");
|
const LabjackYaesu = @import("./LabjackYaesu.zig");
|
||||||
|
|
||||||
const RotCtl = @This();
|
const RotCtl = @This();
|
||||||
@ -113,6 +114,27 @@ fn getPosition(self: *RotCtl, _: []const u8, tokens: *TokenIter) CommandError!vo
|
|||||||
self.printReply("{d:.1}\n{d:.1}", .{ pos.azimuth, pos.elevation }) catch return error.BadOutput;
|
self.printReply("{d:.1}\n{d:.1}", .{ pos.azimuth, pos.elevation }) catch return error.BadOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn inRange(request: f64, comptime dof: enum { azimuth, elevation }) bool {
|
||||||
|
return switch (dof) {
|
||||||
|
// zig fmt: off
|
||||||
|
.azimuth => request >= (
|
||||||
|
config.labjack.feedback_calibration.azimuth.minimum.angle
|
||||||
|
+ config.controller.angle_offset.azimuth
|
||||||
|
) and request <= (
|
||||||
|
config.labjack.feedback_calibration.azimuth.maximum.angle
|
||||||
|
+ config.controller.angle_offset.azimuth
|
||||||
|
),
|
||||||
|
.elevation => request >= (
|
||||||
|
config.labjack.feedback_calibration.elevation.minimum.angle
|
||||||
|
+ config.controller.angle_offset.elevation
|
||||||
|
) and request <= (
|
||||||
|
config.labjack.feedback_calibration.elevation.maximum.angle
|
||||||
|
+ config.controller.angle_offset.elevation
|
||||||
|
),
|
||||||
|
// zig fmt: on
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn setPosition(self: *RotCtl, _: []const u8, tokens: *TokenIter) CommandError!void {
|
fn setPosition(self: *RotCtl, _: []const u8, tokens: *TokenIter) CommandError!void {
|
||||||
const azimuth = std.fmt.parseFloat(f64, tokens.next() orelse {
|
const azimuth = std.fmt.parseFloat(f64, tokens.next() orelse {
|
||||||
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
||||||
@ -120,12 +142,18 @@ fn setPosition(self: *RotCtl, _: []const u8, tokens: *TokenIter) CommandError!vo
|
|||||||
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!inRange(azimuth, .azimuth))
|
||||||
|
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
||||||
|
|
||||||
const elevation = std.fmt.parseFloat(f64, tokens.next() orelse {
|
const elevation = std.fmt.parseFloat(f64, tokens.next() orelse {
|
||||||
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
||||||
}) catch {
|
}) catch {
|
||||||
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!inRange(elevation, .elevation))
|
||||||
|
return self.replyStatus(.invalid_parameter) catch error.BadOutput;
|
||||||
|
|
||||||
self.rotator.setTarget(.{ .azimuth = azimuth, .elevation = elevation });
|
self.rotator.setTarget(.{ .azimuth = azimuth, .elevation = elevation });
|
||||||
return self.replyStatus(.okay) catch error.BadOutput;
|
return self.replyStatus(.okay) catch error.BadOutput;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user