Random bad changes do not read

This commit is contained in:
Matthias Portzel 2024-04-05 21:08:09 -04:00
parent 1f4f39e519
commit 91a32fdd52
No known key found for this signature in database
6 changed files with 334 additions and 24 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
zig-cache/
zig-out/
*.pdf

View File

@ -4,6 +4,12 @@ This creates two main files:
* `zig-out/firmware/micromouse.uf2` which can be uploaded to an RP2040.
* `zig-out/bin/micromouse` which can be run on the host computer in simulation
# Simulation
Download the mms simulator from https://github.com/mackorone/mms/releases.
(I installed this to my Applications folder.)
Pop open a new Mouse in the simulator by clicking the plus next to the "Mouse" selector.
Point it at this directory. Set it up with `/usr/local/bin/zig build` as the build command and `./zig-out/bin/micromouse` as the run command.
# Overview / Assumptions
We're using the same coordinate space as the simulator (mms). This is "math coords", with 0, 0 in the lower left and positive y up. North is up
@ -19,12 +25,6 @@ TODO: test with non-square mazes. I did my best but I don't know
Use std.log.debug. microzig. yeah
# Simulation
Download the mms simulator from https://github.com/mackorone/mms/releases.
(I installed this to my Applications folder.)
Pop open a new Mouse in the simulator by clicking the plus next to the "Mouse" selector.
Point it at this directory. Set it up with `/usr/local/bin/zig build` as the build command and `./zig-out/bin/micromouse` as the run command.
# Sending patches
Git is decentralized, which means you don't need an account on Tildegit in order to contribute. Simply clone, make your changes, and commit like normal.

BIN
image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

View File

@ -55,17 +55,24 @@ const Node = struct {
return nodes;
}
// Distance from true center (the post in the middle of the 2x2 square) rounded down
//
fn getCrowDistance(self: *const Node) usize {
return self.p.x + self.p.y;
}
pub fn updateScore(self: *Node, newScore: usize) void {
// newScore should be less than the current score
assert(newScore <= self.score);
self.score = newScore;
// Call updateScore on all adjacent nodes if they have a score which is worse than (newScore + 1)
// For some reason BoundedArrays aren't indexable
// Call updateScore on all adjacent nodes if they have a score which is worse than (newScore + 100)
// For some reason BoundedArrays aren't indexable, hence the .slice()
const adjacentNodes = self.getAdjacentNodes().slice();
for (adjacentNodes) |node| {
if (self.score + 1 < node.score) {
node.updateScore(self.score + 1);
// 1 square away is a score of 100. This lets us play with tiebreaker metrics
if (self.score + 100 < node.score) {
node.updateScore(self.score + 100);
}
}
@ -243,6 +250,9 @@ pub fn floodFill(dest: []const Point) void {
for (adjacentNodes) |n| {
std.log.debug("Node at ({}, {}) has score {}", .{ n.p.x, n.p.y, n.score });
assert(@TypeOf(n) == *Node);
// Replace minAdjacent if this new node is shorter
//
if (minAdjacent == null or n.score < minAdjacent.?.score) {
minAdjacent = n;
}

View File

@ -4,15 +4,52 @@ const algo = @import("algorithm.zig");
const robot = algo.robot;
const map = @import("map.zig");
const rp2040 = @import("microzig").hal;
// const multicore = rp2040.multicore;
// TODO: move into algo
pub fn alt_core () noreturn {
// while true
// Flash pin 6 for now
while (true) {
if (is_robot) {
robot.toggle_led_6();
}
}
}
const is_robot = algo.is_robot;
// // TODO: Refactor again. algo.is_robot???
// if (algo.is_robot) {
// alt_core
// }
const time = @import("microzig").hal.time;
// Entry point for second core
fn core1 () noreturn {
time.sleep_ms(1000);
alt_core();
}
pub fn main() !noreturn {
// Power On test
// TODO: rename is_robot to is_physical or something
if (!is_robot) {
// TODO: spawn a thread to run alt-core operations
}else {
// multicore.launch_core1(core1);
}
algo.setup();
// Flood fill to the goal
algo.floodFill(map.goals[0..]);
// // Flood fill to the goal
// algo.floodFill(map.goals[0..]);
// Flood fill back to the start
const starts = [_]map.Point{ map.start };
algo.floodFill(starts[0..]);
// // Flood fill back to the start
// const starts = [_]map.Point{ map.start };
// algo.floodFill(starts[0..]);
robot.stall();
}

View File

@ -8,13 +8,193 @@ const map = @import("map.zig");
const microzig = @import("microzig");
const rp2040 = microzig.hal;
const time = rp2040.time;
const i2c = rp2040.i2c;
const gpio = rp2040.gpio;
const pin_config = rp2040.pins.GlobalConfiguration {
.GPIO25 = .{
.name = "onboard_led",
.direction = .out,
},
// TODO: Fill in the rest
// 6 colored LEDs
.GPIO0 = .{
.name = "led_4",
.direction = .out,
},
.GPIO1 = .{
.name = "led_3",
.direction = .out,
},
.GPIO2 = .{
.name = "led_5",
.direction = .out,
},
.GPIO3 = .{
.name = "led_2",
.direction = .out,
},
.GPIO4 = .{
.name = "led_6",
.direction = .out,
},
.GPIO5 = .{
.name = "led_1",
.direction = .out,
},
// 3 of the 5 LiDAR clock enable pins
// Instead of writing 1 to the CE pins, we should set them as inputs and change them to pull-high
// Then we set as an output and write 0
// This is because the sensor board is actually running at 1.8V
// Each LiDAR has:
// GPIO0 - enable pin, must be pulled high during boot and when using the chip, this is our ce pin
// SCL
// SDA
// We don't need to worry about these pins in software, they're wired in!
// GPIO1 -
// AVDD - needs power second
// AVSS_VCSEL
// AVDD_VCSEL - needs power first
// The config here doesn't really matter because we dynamically update these every time we write to them.
.GPIO6 = .{
// LCE3
.name = "lidar_front_left_ce",
.direction = .out,
},
.GPIO7 = .{
// LCE5
.name = "lidar_front_ce",
.direction = .out,
},
.GPIO8 = .{
// LCE1
.name = "lidar_back_left_ce",
.direction = .out,
},
// Motors
.GPIO9 = .{
// M/Fault ("indicates an error condition in the motor controller (such as over current)")
.name = "motor_fault",
.direction = .in,
},
// Motor Right (or B)
.GPIO10 = .{
// MB2
.name = "motor_right_2",
.direction = .out,
},
.GPIO11 = .{
// MB1
.name = "motor_right_1",
.direction = .out,
},
// Motor Left (or A)
.GPIO12 = .{
// MA2
.name = "motor_left_2",
.direction = .out,
},
.GPIO13 = .{
// MA1
.name = "motor_left_1",
.direction = .out,
},
// Motor Encoders
// Zach recommends triggering a double-edged interrupter on 1 and clocking on 2
// You read the second to know if you're going forward or backwards
.GPIO14 = .{
// MAE2
.name = "motor_left_encoder_1",
.direction = .in,
},
.GPIO15 = .{
// MAE1
.name = "motor_left_encoder_2",
.direction = .in,
},
.GPIO16 = .{
// MBE2
.name = "motor_right_encoder_2",
.direction = .in,
},
.GPIO17 = .{
// MBE1
.name = "motor_right_encoder_1",
.direction = .in,
},
// Buttons
.GPIO18 = .{
// BTN1
.name = "button_1",
.direction = .in,
},
.GPIO19 = .{
// BTN2
.name = "button_2",
.direction = .in,
},
// SD Card
// .GPIO20 = .{
// // SD_MISO
// .name = "button_2",
// .direction = .in,
// },
// .GPIO21 = .{
// // SD_CSB
// .name = "button_2",
// .direction = .in,
// },
// .GPIO22 = .{
// // SD_CLK
// .name = "button_2",
// .direction = .in,
// },
// .GPIO23 = .{
// // SD_MOSI
// .name = "button_2",
// .direction = .in,
// },
// LiDAR signals
// These aren't GPIO pins, they're I2C pins, so we don't need to configure them here
// .GPIO24 = .{
// // SCL
// .name = "",
// .direction = .out,
// },
// .GPIO25 = .{ // This is the on board LED on the Pico
// // SDA
// .name = "",
// .direction = .out,
// },
// 2 of the 5 encoders
.GPIO26 = .{
// LCE2
.name = "lidar_back_right_ce",
.direction = .out,
// .pull =
},
.GPIO27 = .{
// LCE4
.name = "lidar_front_right_ce",
.direction = .out,
},
// Motor Current monitoring
// These pins support Analog-Digital Conversion, which is cool
// TODO: What do these do? What do we do with them?
.GPIO28 = .{
// MAI
.name = "ma_i",
.direction = .in,
},
.GPIO29 = .{
// MBI
.name = "mb_i",
.direction = .in,
},
};
// comptime {
// @compileLog(@typeInfo(@TypeOf(pin_config.apply)));
@ -27,13 +207,57 @@ const RIGHT_MOTOR = 2;
// 254mm square size
const SQUARE_SIZE = 254;
var pins: rp2040.pins.Pins(pin_config) = undefined;
pub fn toggle_led_6 () void {
// TODO: this does bad things if pins hasn't been defined by the first core yet
pins.led_5.toggle();
}
// Zach confirms i2c 0
// const i2c0 = i2c.num(0);
// Pin stuff
pub fn setup () void {
const pins = pin_config.apply();
pins = pin_config.apply();
pins.onboard_led.toggle();
pins.onboard_led.toggle();
// const lidar_ce_pins = [_]microzig.hal.gpio.Pin{
// pins.lidar_front_left_ce,
// pins.lidar_front_right_ce,
// pins.lidar_back_right_ce,
// pins.lidar_back_left_ce,
// pins.lidar_front_ce,
// };
// _ = i2c0.apply(.{
// .clock_config = rp2040.clock_config, // Zach says the default here is fine
// .scl_pin = gpio.num(24),
// .sda_pin = gpio.num(25),
// });
// // We need to setup the LiDAR addresses
// // TODO: Create a Lidar struct with methods
// // The way we're doing this right now, we are enabling every LiDAR
// const LIDAR_ADDR_BASE: i2c.Address = @enumFromInt(0x50);
// // Disable all of them
// for (lidar_ce_pins) |pin| {
// pin.set_direction(.out);
// pin.put(0);
// }
// // One by one, enable and give an address
// var current_address = LIDAR_ADDR_BASE;
// for (lidar_ce_pins) |pin| {
// // Enable
// pin.set_direction(.in);
// pin.set_pull(.up);
// // Write an address
// i2c0.set_address(current_address);
// current_address = @enumFromInt(@intFromEnum(current_address) + 1);
// }
// pins.onboard_led.toggle();
// pins.onboard_led.toggle();
// TODO
}
@ -68,8 +292,46 @@ pub fn readBack() bool {
}
pub fn stall() noreturn {
pins.motor_right_1.put(1);
pins.motor_right_2.put(0);
pins.motor_left_1.put(1);
pins.motor_left_2.put(0);
time.sleep_ms(5000);
pins.motor_right_1.put(0);
pins.motor_right_2.put(0);
pins.motor_left_1.put(0);
pins.motor_left_2.put(0);
while (true) {
// pins.onboard_led.toggle();
time.sleep_ms(1000);
// const b1 = pins.button_1.read();
// const b2 = pins.button_2.read();
// pins.led_1.put(b1);
// pins.led_6.put(b2);
time.sleep_ms(10);
// pins.led_1.put(0);
// pins.led_2.put(1);
// time.sleep_ms(500);
// pins.led_2.put(0);
// pins.led_3.put(1);
// time.sleep_ms(500);
// pins.led_3.put(0);
// pins.led_4.put(1);
// time.sleep_ms(500);
// pins.led_4.put(0);
// pins.led_6.put(1);
// time.sleep_ms(500);
// pins.led_6.put(0);
}
}