관리 메뉴

드럼치는 프로그래머

[시스템분석및설계] 19장 원격 조정 로봇 설계 예비레포트 본문

★─Multi Media/☆─2학년 2학기

[시스템분석및설계] 19장 원격 조정 로봇 설계 예비레포트

드럼치는한동이 2008. 3. 14. 03:01

◎ 실험 목적

원격 조정 로봇의 동작을 VHDL로 기술하고, 시뮬레이션을 통해 동작을 검증한다.

 

◎ 이론 설명

▶ 원격 조정 로봇 설계

① 원격 조정이란 사용자로부터 멀리 떨어진 곳에 있는 대상을 조정한다는 뜻이다.

② 3-key로 되어 있는 송신기에서 key를 누르면 미리 약속된 대로, 직진, 후진 또는 좌회전, 우회전 주행을 하도록 되어 있다.

③ 원격 조정 로봇은 트레이닝 키트에 있는 무선 통신 수신 보드와 FPGA 보드, 그리고 모 터부를 조립하면 완성된다.

④ 무선 통신 제어기에서는 송신기에서 눌려진 key의 상태를 그대로 LED로 내보내어 불을 켜도록 했었는데, 이제는 그 눌려진 상태에 따라 적절히 2개의 스텝 모터를 회전시켜 로봇을 움지경 주도록 한다.

⑤ Key를 통한 로봇의 조정

Key 조작

RF_DATA(2:0)

로봇 동작

3번 누름

100

전진

1번 누름

001

후진

2, 3번 동시 누름

110

우회전

1, 2번 동시 누름

011

좌회전

그 외

000 등

정지

 

 

 

◎ 실험 장비

▶ Xilinx ISE

▶ ModelSIM

▶ Rov-Lab 트레이닝 키트

 

 

◎ 실험 순서

▶ 원격 조정 로봇 설계

① 원격 조정 로봇의 동작을 VHDL로 기술

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity rc_ro_vhdl is

Port ( RSTB : in STD_LOGIC;

CLK_4M : in STD_LOGIC;

RF_DATA : in STD_LOGIC_VECTOR(2 downto 0);

MTL_A : out STD_LOGIC;

MTL_B : out STD_LOGIC;

MTL_nA : out STD_LOGIC;

MTL_nB : out STD_LOGIC;

MTR_A : out STD_LOGIC;

MTR_B : out STD_LOGIC;

MTR_nA : out STD_LOGIC;

MTR_nB : out STD_LOGIC);

end rc_ro_vhdl;

architecture Behavioral of rc_ro_vhdl is

signal forward : std_logic;

signal mtl_speed : std_logic_vector (1 downto 0);

signal mtr_speed : std_logic_vector (1 downto 0);

signal speed_l : integer range 0 to 25000;

signal speed_r : integer range 0 to 25000;

signal motor_lcnt : integer range 0 to 25000;

signal phase_lclk : std_logic;

signal motor_rcnt : integer range 0 to 25000;

signal phase_rclk : std_logic;

signal phase_lcnt : std_logic_vector (1 downto 0);

signal phase_lout : std_logic_vector (3 downto 0);

signal phase_rcnt : std_logic_vector (1 downto 0);

signal phase_rout : std_logic_vector (3 downto 0);

begin

--===== RF data에 따른 좌,우 모터 속도값 결정 =================

process(RF_DATA)

begin

forward <= '1';

 

case RF_DATA is

when "100" => mtl_speed <= "11";

mtr_speed <= "11"; -- 빠른 직진

when "001" => mtl_speed <= "11";

mtr_speed <= "11";

forward <= '0';

-- 빠른 후진

when "110" => mtl_speed <= "11";

mtr_speed <= "00"; -- 빠른 우회전

when "011" => mtl_speed <= "00";

mtr_speed <= "11"; -- 빠른 좌회전

when others => mtl_speed <= "00";

mtr_speed <= "00"; -- 정지

end case;

end process;

--===== 속도값에 따른 좌,우모터 속도결정 =======================

process(mtl_speed)

variable for_sim : std_logic;

begin

for_sim := '0'; -- 1 : 시뮬레이션시 0 : 정상동작시

if for_sim = '0' then

case mtl_speed is

when "00" => speed_l <= 0;

-- 0 Hz

when "01" => speed_l <= 19999;

-- 100 Hz

when "10" => speed_l <= 9999;

-- 200 Hz

when "11" => speed_l <= 6249;

-- 320 Hz

when others => speed_l <= 6249;

end case;

else

case mtl_speed is

when "00" => speed_l <= 0;

when "01" => speed_l <= 8;

when "10" => speed_l <= 4;

process(mtr_speed)

variable for_sim : std_logic;

begin

for_sim := '0'; -- 1 : 시뮬레이션시 0 : 정상동작시

if for_sim = '0' then

case mtr_speed is

when "00" => speed_r <= 0;

-- 0 Hz

when "01" => speed_r <= 19999;

-- 100 Hz

when "10" => speed_r <= 9999;

-- 200 Hz

when "11" => speed_r <= 6249;

-- 320 Hz

when others => speed_r <= 6249;

end case;

else

case mtr_speed is

when "00" => speed_r <= 0;

when "01" => speed_r <= 8;

when "10" => speed_r <= 4;

when "11" => speed_r <= 2;

when others => speed_r <= 2;

end case;

end if;

end process;

process(RSTB, speed_l, CLK_4M, motor_lcnt)

begin

if RSTB = '0' or speed_l = 0 then

motor_lcnt <= 0;

phase_lclk <= '0';

elsif rising_edge (CLK_4M) then

if (motor_lcnt >= speed_l) then

motor_lcnt <= 0;

phase_lclk <= not phase_lclk;

else

motor_lcnt <= motor_lcnt + 1;

process(RSTB, speed_r, CLK_4M, motor_rcnt)

begin

if RSTB = '0' or speed_r = 0 then

motor_rcnt <= 0;

phase_rclk <= '0';

elsif rising_edge (CLK_4M) then

if (motor_rcnt >= speed_r) then

motor_rcnt <= 0;

phase_rclk <= not phase_rclk;

else

motor_rcnt <= motor_rcnt + 1;

end if;

end if;

end process;

--===== 왼쪽 모터 phase Output(1상 여자방식) ================

process(RSTB, phase_lclk, phase_lcnt)

begin

if RSTB = '0' then

phase_lcnt <= (others => '0');

elsif rising_edge (phase_lclk) then

phase_lcnt <= phase_lcnt + 1;

end if;

end process;

process(RSTB, phase_lcnt)

begin

if RSTB = '0' then

phase_lout <= (others => '0');

else

case phase_lcnt is

when "00" => phase_lout <= "1000";

when "01" => phase_lout <= "0100";

when "10" => phase_lout <= "0010";

when "11" => phase_lout <= "0001";

when others => phase_lout <= "0000";

end case;

end if;

end process;

 

--===== 오른쪽 모터 phase Output(1상 여자방식) ==============

process(RSTB, phase_rclk, phase_rcnt)

begin

if RSTB = '0' then

phase_rcnt <= (others => '0');

elsif rising_edge (phase_rclk) then

phase_rcnt <= phase_rcnt + 1;

end if;

end process;

process(RSTB, phase_rcnt)

begin

if RSTB = '0' then

phase_rout <= (others => '0');

else

case phase_rcnt is

when "00" => phase_rout <= "0001";

when "01" => phase_rout <= "0010";

when "10" => phase_rout <= "0100";

when "11" => phase_rout <= "1000";

when others => phase_rout <= "0000";

end case;

end if;

end process;

--=======================================================

MTL_A <= phase_lout(0) when forward = '1' else phase_lout(3);

MTL_B <= phase_lout(1) when forward = '1' else phase_lout(2);

MTL_nA <= phase_lout(2) when forward = '1' else phase_lout(1);

MTL_nB <= phase_lout(3) when forward = '1' else phase_lout(0);

MTR_A <= phase_rout(0) when forward = '1' else phase_rout(3);

MTR_B <= phase_rout(1) when forward = '1' else phase_rout(2);

MTR_nA <= phase_rout(2) when forward = '1' else phase_rout(1);

MTR_nB <= phase_rout(3) when forward = '1' else phase_rout(0);

end Behavioral;

 

② TestBenchWaveform으로 시뮬레이션

주어진 입력(RSTB, CLK_4M, RF_DATA)에 따라

출력(MTL_A, MTL_B, MTL_nA, MTL_nB, MTR_A, MTR_B, MTR_nA, MTR_nB)이 진리표대로 정확하게 출력되는지를 검증

 

③ 트레이닝 키트로 동작 검증

주어진 입력(RSTB, CLK_4M, RF_DATA)에 따라

출력(MTL_A, MTL_B, MTL_nA, MTL_nB, MTR_A, MTR_B, MTR_nA, MTR_nB)이 진리표대로 정확하게 출력되는지를 검증

Comments