rotctl: hook up P interface

This appears to work. Now all that remains is doing the rest of the
work.
This commit is contained in:
torque 2024-07-03 17:42:36 -07:00
parent c8bec6a7c5
commit dbbb5c1748
Signed by: torque
SSH Key Fingerprint: SHA256:nCrXefBNo6EbjNSQhv0nXmEg/VuNq3sMF5b8zETw3Tk
3 changed files with 34 additions and 15 deletions

View File

@ -55,6 +55,7 @@ controller: ControllerConfig = .{
.loop_interval_ns = 50_000_000,
.parking_posture = .{ .azimuth = 180, .elevation = 90 },
.angle_tolerance = .{ .azimuth = 1, .elevation = 1 },
.angle_offset = .{ .azimuth = 0, .elevation = 0 },
},
pub const VoltAngle = struct { voltage: f64, angle: f64 };
@ -104,6 +105,7 @@ const ControllerConfig = struct {
loop_interval_ns: u64,
parking_posture: AzEl,
angle_tolerance: AzEl,
angle_offset: AzEl,
const OutPair = struct {
increase: lj.DigitalOutputChannel,

View File

@ -44,6 +44,13 @@ pub fn setTarget(self: LabjackYaesu, target: AzEl) void {
controller.requested_state = .running;
}
pub fn position(self: LabjackYaesu) AzEl {
self.lock.lock();
defer self.lock.unlock();
return self.controller.position;
}
pub fn startCalibration(self: LabjackYaesu) void {
// there are two different types of calibration:
// 1. feedback calibration, running to the extents of the rotator

View File

@ -51,7 +51,9 @@ pub fn run(allocator: std.mem.Allocator) !void {
while (interface.running) : (fbs.reset()) {
reader.streamUntilDelimiter(fbs.writer(), '\n', readbuffer.len) catch break;
try interface.handleHamlibCommand(fbs.getWritten());
try interface.handleHamlibCommand(
std.mem.trim(u8, fbs.getWritten(), &std.ascii.whitespace),
);
}
}
}
@ -65,6 +67,11 @@ fn replyStatus(self: *RotCtl, comptime status: HamlibErrorCode) !void {
try self.write(comptime status.replyFrame() ++ "\n");
}
fn printReply(self: *RotCtl, comptime fmt: []const u8, args: anytype) !void {
try self.writer.writer().print(fmt ++ "\n", args);
try self.writer.flush();
}
fn handleHamlibCommand(
self: *RotCtl,
command: []const u8,
@ -74,25 +81,26 @@ fn handleHamlibCommand(
const first = tokens.next().?;
if (first.len == 1 or first[0] == '\\') {
switch (first[0]) {
'q' => {
'q', 'Q' => {
self.running = false;
self.replyStatus(.okay) catch return;
self.replyStatus(.okay) catch {};
self.rotator.stop();
},
'P' => {
const pos = self.rotator.position();
try self.printReply("{d:.1} {d:.1}", .{ pos.azimuth, pos.elevation });
},
'\\' => {
return try self.parseLongCommand(first[1..], &tokens);
try self.parseLongCommand(first[1..], &tokens);
},
else => |cmd| {
log.err("unknown command {}", .{cmd});
else => {
log.err("unknown short command '{s}'", .{command});
try self.replyStatus(.not_implemented);
},
}
} else if (std.mem.eql(u8, first, "AOS")) {
// gpredict just kind of shoves this message in on top of the HamLib
// protocol.
try self.replyStatus(.okay);
} else if (std.mem.eql(u8, first, "LOS")) {
try self.replyStatus(.okay);
} else try self.replyStatus(.not_supported);
} else {
try self.parseLongCommand(first, &tokens);
}
}
fn parseLongCommand(
@ -105,12 +113,12 @@ fn parseLongCommand(
for (rotctl_commands) |check| {
if (check.long) |long| {
if (command.len >= long.len and std.mem.eql(u8, long, command)) {
log.warn("Unsupported command {s}", .{command});
log.warn("Unsupported long command {s}", .{command});
break;
}
}
} else {
log.warn("Unknown command {s}", .{command});
log.warn("Unknown long command '{s}'", .{command});
}
return self.replyStatus(.not_supported);
}
@ -154,6 +162,8 @@ const HamlibCommand = struct {
const rotctl_commands = [_]HamlibCommand{
.{ .short = 'q' }, // quit
.{ .short = 'Q' }, // quit
.{ .long = "AOS" },
.{ .long = "LOS" },
.{ .short = 'P', .long = "set_pos" }, // azimuth: f64, elevation: f64
.{ .short = 'p', .long = "get_pos" }, // return az: f64, el: f64
.{ .short = 'M', .long = "move" }, // direction: enum { up=2, down=4, left=8, right=16 }, speed: i8 (0-100 or -1)