공부/Embedded

[라즈베리파이] senseHat LED Controller

래울 2024. 4. 17. 09:22

- 기울이면 Player가 이동

from sense_hat import SenseHat
from time import sleep

sense = SenseHat()
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
white = (255, 255, 255)
black = (0, 0, 0)

class Game():
    def __init__(self):
        self.size = 8
        self.board = [
        [0, 1, 0, 0, 0, 0, 0, 0],
        [0, 1, 1, 1, 1, 1, 1, 0],
        [0, 0, 0, 0, 0, 0, 1, 0],
        [0, 1, 1, 1, 1, 0, 1, 0],
        [0, 0, 1, 0, 0, 0, 1, 0],
        [0, 0, 1, 0, 1, 1, 1, 0],
        [0, 1, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 1, 1, 1, 0]
        ]
        self.player = [0, 0]
        self.goal = [self.size - 1, self.size - 1]

    def PrintInfo(self):
        print("size : ", self.size)
        for i in self.board:
            for j in i:
                print(j, end='')
            print()

    def PrintMap(self):
        #sense.set_pixel(self.player[1], self.player[0], green)
        for i in range(self.size):
            for j in range(self.size):
                sense.set_pixel(j, i, red if self.board[i][j] else white)
        sense.set_pixel(self.player[1], self.player[0], green)
        #sense.set_pixel(self.goal[1], self.goal[0], green)

    def FindPath(self):
        #part2
        pass

    def GetGyroSense(self):
        # Sense HAT에서 가속도 및 방향 데이터 가져오기
        acceleration = sense.get_accelerometer_raw()
        # X, Y, Z 축 가속도 값 가져오기
        acc_x = acceleration['x']
        acc_y = acceleration['y']
        acc_z = acceleration['z']
        # X, Y 축의 기울기 계산 (라디안 값)
        roll_rad = -1 * (acc_x / ((acc_y ** 2 + acc_z ** 2) ** 0.5))
        pitch_rad = -1 * (acc_y / ((acc_x ** 2 + acc_z ** 2) ** 0.5))
        # 라디안 값을 각도로 변환 (degrees)
        roll = roll_rad * 180 / 3.14
        pitch = pitch_rad * 180 / 3.14
        # 결과 출력
        #print("Roll: {:.2f} degrees".format(roll))
        #print("Pitch: {:.2f} degrees".format(pitch))
        return [roll, pitch]

        #### prev.
        gyro = sense.get_gyroscope()
        x = gyro['pitch']
        y = gyro['roll']
        z = gyro['yaw']
        #print(f"Gyro - X:{x}, Y:{y}, Z:{z}")
        return [x, y, z]

    def Left(self):
        y, x = self.player
        nx = x - 1
        if nx < 0 or self.board[y][nx]: return [y, x]
        else: return [y, nx]

    def Right(self):
        y, x = self.player
        nx = x + 1
        if nx >= self.size or self.board[y][nx]: return [y, x]
        else: return [y, nx]

    def Top(self):
        y, x = self.player
        ny = y - 1
        if ny < 0 or self.board[ny][x]: return [y, x]
        else: return [ny, x]

    def Down(self):
        y, x = self.player
        ny = y + 1
        if ny >= self.size or self.board[ny][x]: return [y, x]
        else: return [ny, x]

    def Run(self):
        sense.set_pixel(self.player[1], self.player[0], white)
        x, y = self.GetGyroSense()
        print(f"Gyro - roll:{x}, pitch:{y}")
        # print(f"Player - X:{self.player[1]}, Y:{self.player[0]}")
        if x > 20 and x < 180:
            print("Left")
            self.player = self.Left()
        elif x < -20 and x > -180:
            print("Right")
            self.player = self.Right()
        elif y < -20 and y > -180:
            print("Down")
            self.player = self.Down()
        elif y < 180 and y > 20:
            print("Top")
            self.player = self.Top()
        sense.set_pixel(self.player[1], self.player[0], green)
        sleep(1)

    def __del__(self):
        sense.clear()


def main():
    print("main!")
    game = Game()
    game.PrintInfo()
    game.PrintMap()
    while True:
        game.Run()

if __name__ == "__main__":
    main()

 

 

- 모든 경로를 출력

- 버튼 클릭 시 다른 경로 출력

from sense_hat import SenseHat, ACTION_PRESSED, ACTION_HELD, ACTION_RELEASED
from time import sleep
from signal import pause

sense = SenseHat()
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
white = (255, 255, 255)
black = (0, 0, 0)

class Game():
    def __init__(self):
        self.size = 8
        self.board = [
        [0, 1, 0, 0, 0, 0, 0, 0],
        [0, 1, 1, 1, 1, 0, 1, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 1, 1, 1, 0, 1, 0],
        [0, 0, 1, 0, 0, 0, 1, 0],
        [0, 0, 1, 0, 1, 1, 1, 0],
        [0, 1, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 1, 1, 1, 0]
        ]
        self.player = [0, 0]
        self.goal = [self.size - 1, self.size - 1]

    def PrintInfo(self):
        print("size : ", self.size)
        for i in self.board:
            for j in i:
                print(j, end='')
            print()

    def PrintMap(self):
        #sense.set_pixel(self.player[1], self.player[0], green)
        for i in range(self.size):
            for j in range(self.size):
                sense.set_pixel(j, i, red if self.board[i][j] else white)
        sense.set_pixel(self.player[1], self.player[0], green)
        #sense.set_pixel(self.goal[1], self.goal[0], green)

    def dfs(self, p, y, x):
        if y == self.goal[0] and x == self.goal[1]:
            self.path.append(p.copy())
            return
        dy = [1, 0, -1, 0]
        dx = [0, 1, 0, -1]
        for k in range(4):
            yy = dy[k] + y
            xx = dx[k] + x
            if xx < 0 or yy < 0 or xx >= self.size or yy >= self.size or self.check[yy][xx] or self.board[yy][xx]: continue
            self.check[yy][xx] = 1
            p.append([yy, xx])
            self.dfs(p, yy, xx)
            p.pop()
            self.check[yy][xx] = 0


    def FindPath(self):
        self.check = [[0 for i in range(self.size)] for j in range(self.size)]
        self.path = []
        self.dfs([], self.player[0], self.player[1])
        self.btnCnt = 0
        print(len(self.path))

    def PrintPath(self):
        currPathNum = self.btnCnt % len(self.path)
        # map init
        self.PrintMap()
        for i in self.path[currPathNum]:
            sense.set_pixel(i[1], i[0], green)
            sleep(0.1)

    def PushButton(self, event):
        if event.action != ACTION_RELEASED:
            self.PrintPath()
            self.btnCnt += 1

    def Run(self):
        # sense.set_pixel(self.player[1], self.player[0], white)
        # sense.set_pixel(self.player[1], self.player[0], green)
        sense.stick.direction_any = self.PushButton
        #sense.clear()
        pause()

    def __del__(self):
        sense.clear()


def main():
    print("main!")
    game = Game()
    game.PrintInfo()
    game.PrintMap()
    game.FindPath()
    game.Run()
    #sense.clear()

if __name__ == "__main__":
    main()

 

 

- 조이스틱 이동

- 목적지까지 최단 경로로 LED 경로 출력

from sense_hat import SenseHat, ACTION_PRESSED, ACTION_HELD, ACTION_RELEASED
from time import sleep
from signal import pause
from collections import deque

sense = SenseHat()
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
white = (255, 255, 255)
black = (0, 0, 0)

class Game():
    def __init__(self):
        self.size = 8
        self.board = [
        [0, 1, 0, 0, 0, 0, 0, 0],
        [0, 1, 1, 1, 1, 0, 1, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 1, 1, 1, 0, 1, 0],
        [0, 0, 1, 0, 0, 0, 1, 0],
        [0, 0, 1, 0, 1, 1, 1, 0],
        [0, 1, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 1, 1, 1, 0]
        ]
        self.player = [0, 0]
        self.goal = [self.size - 1, self.size - 1]

    def PrintInfo(self):
        print("size : ", self.size)
        for i in self.board:
            for j in i:
                print(j, end='')
            print()

    def PrintMap(self):
        #sense.set_pixel(self.player[1], self.player[0], green)
        for i in range(self.size):
            for j in range(self.size):
                sense.set_pixel(j, i, red if self.board[i][j] else white)
        sense.set_pixel(self.player[1], self.player[0], green)


    def FindPath(self):
        dy = [1, -1, 0, 0]
        dx = [0, 0, 1, -1]
        check = [[0 for i in range(self.size)] for j in range(self.size)]
        path = [[[] for i in range(self.size)] for j in range(self.size)]
        y, x = self.player
        queue = deque([[y, x]])
        check[y][x] = 1
        flag = False
        while len(queue):
            qSize = len(queue)
            for i in range(qSize):
                now = queue.popleft()
                if now[0] == self.goal[0] and now[1] == self.goal[1]:
                    print("end!")
                    flag = True
                    break
                for k in range(4):
                    y = dy[k] + now[0]
                    x = dx[k] + now[1]
                    if y < 0 or x < 0 or y >= self.size or x >= self.size or check[y][x] or self.board[y][x]: continue
                    path[y][x] = now
                    queue.append([y, x])
                    check[y][x] = 1
            if flag:
                break

        #print path
        start = self.goal
        while path[start[0]][start[1]]:
            sense.set_pixel(start[1], start[0], blue)
            sleep(0.1)
            start = path[start[0]][start[1]]

        sleep(1)
        start = self.goal
        while path[start[0]][start[1]]:
            sense.set_pixel(start[1], start[0], white)
            start = path[start[0]][start[1]]

    def pushed_up(self, event):
        if event.action != ACTION_RELEASED:
            y, x = self.player
            #sense.set_pixel(x, y, white)
            if y - 1 < 0 or self.board[y - 1][x]: return
            self.player = [y - 1, x]
            y, x = self.player
            print("y:%d, x:%d" %(y, x))
            sense.clear()
            self.PrintMap()
            self.FindPath()
            sense.set_pixel(x, y, green)


    def pushed_down(self, event):
        if event.action != ACTION_RELEASED:
            y, x = self.player
            #sense.set_pixel(x, y, white)
            if y + 1 >= self.size or self.board[y + 1][x]: return
            self.player = [y + 1, x]
            y, x = self.player
            print("y:%d, x:%d" %(y, x))
            sense.clear()
            self.PrintMap()
            self.FindPath()
            sense.set_pixel(x, y, green)


    def pushed_left(self, event):
        if event.action != ACTION_RELEASED:
            y, x = self.player
            #sense.set_pixel(x, y, white)
            if x - 1 < 0 or self.board[y][x - 1]: return
            self.player = [y, x - 1]
            y, x = self.player
            print("y:%d, x:%d" %(y, x))
            sense.clear()
            self.PrintMap()
            self.FindPath()
            sense.set_pixel(x, y, green)


    def pushed_right(self, event):
        if event.action != ACTION_RELEASED:
            y, x = self.player
            #sense.set_pixel(x, y, white)
            if x + 1 >= self.size or self.board[y][x + 1]: return
            self.player = [y, x + 1]
            y, x = self.player
            print("y:%d, x:%d" %(y, x))
            sense.clear()
            self.PrintMap()
            self.FindPath()
            sense.set_pixel(x, y, green)


    def refresh(self):
        sleep(0.2)
        y, x = self.player
        print("y:%d, x:%d" %(y, x))
        sense.clear()
        self.PrintMap()
        self.FindPath()
        sense.set_pixel(x, y, green)

    def Run(self):
        sense.stick.direction_up = self.pushed_up
        sense.stick.direction_down = self.pushed_down
        sense.stick.direction_left = self.pushed_left
        sense.stick.direction_right = self.pushed_right
        #sense.stick.direction_any = self.refresh
        pause()

    def __del__(self):
        sense.clear()


def main():
    print("main!")
    game = Game()
    game.PrintInfo()
    game.PrintMap()
    game.Run()

if __name__ == "__main__":
    main()