1. 변수와 자료형
Python은 변수를 선언할 때 자료형을 따로 적지 않습니다.
speed = 1.5
robot_name = "mobile_robot"
is_running = True
wheel_count = 4
각 변수의 자료형은 값에 따라 자동으로 정해집니다.
print(type(speed)) # <class 'float'>
print(type(robot_name)) # <class 'str'>
print(type(is_running)) # <class 'bool'>
print(type(wheel_count)) # <class 'int'>
로봇 개발에서 자주 쓰는 기본 자료형은 다음과 같습니다.
| int | 정수 | 10, -3, 0 |
| float | 실수 | 3.14, 0.05 |
| str | 문자열 | "robot" |
| bool | 참/거짓 | True, False |
| list | 순서 있는 여러 값 | [1, 2, 3] |
| tuple | 변경 불가능한 여러 값 | (1, 2, 3) |
| dict | key-value 데이터 | {"x": 1.0, "y": 2.0} |
| set | 중복 없는 집합 | {1, 2, 3} |
2. 숫자 연산
로봇 제어에서는 속도, 각도, 거리, 시간 계산이 많습니다. Python의 기본 연산자는 반드시 익숙해야 합니다.
a = 10
b = 3
print(a + b) # 더하기: 13
print(a - b) # 빼기: 7
print(a * b) # 곱하기: 30
print(a / b) # 나누기: 3.333...
print(a // b) # 몫: 3
print(a % b) # 나머지: 1
print(a ** b) # 거듭제곱: 1000
예를 들어 바퀴 반지름과 각속도를 이용해 선속도를 계산할 수 있습니다.
wheel_radius = 0.05 # meter
angular_velocity = 20.0 # rad/s
linear_velocity = wheel_radius * angular_velocity
print(linear_velocity) # 1.0 m/s
3. 문자열 다루기
로봇 프로그램에서도 문자열은 많이 사용됩니다. 예를 들어 로그 출력, 파일 이름 생성, 장치 이름 설정, 상태 메시지 출력 등에 사용합니다.
robot_name = "delivery_robot"
status = "running"
message = robot_name + " is " + status
print(message)
하지만 실제로는 f-string을 많이 사용합니다.
robot_name = "delivery_robot"
battery = 82.5
print(f"{robot_name} battery: {battery}%")
출력:
delivery_robot battery: 82.5%
소수점 자리수를 제한할 수도 있습니다.
distance = 3.141592
print(f"distance: {distance:.2f} m")
출력:
distance: 3.14 m
로봇 로그에서는 이런 식으로 자주 씁니다.
x = 1.23456
y = -0.98765
yaw = 0.52359
print(f"pose x={x:.3f}, y={y:.3f}, yaw={yaw:.3f}")
4. 리스트
리스트는 여러 값을 순서대로 저장하는 자료형입니다.
sensor_values = [0.1, 0.2, 0.15, 0.3]
값을 하나씩 꺼낼 수 있습니다.
print(sensor_values[0]) # 0.1
print(sensor_values[1]) # 0.2
Python의 인덱스는 0부터 시작합니다.
data = [10, 20, 30, 40]
print(data[0]) # 10
print(data[3]) # 40
print(data[-1]) # 40
print(data[-2]) # 30
리스트에 값을 추가할 수 있습니다.
waypoints = []
waypoints.append([0.0, 0.0])
waypoints.append([1.0, 0.0])
waypoints.append([1.0, 1.0])
print(waypoints)
출력:
[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0]]
리스트 길이는 len()으로 확인합니다.
print(len(waypoints)) # 3
5. 리스트 슬라이싱
리스트에서 일부 구간만 잘라낼 수 있습니다.
data = [10, 20, 30, 40, 50]
print(data[0:3]) # [10, 20, 30]
print(data[1:4]) # [20, 30, 40]
print(data[:3]) # [10, 20, 30]
print(data[2:]) # [30, 40, 50]
기본 슬라이싱 문법
리스트[시작인덱스:끝인덱스]
중요한 규칙은 다음과 같습니다.
시작인덱스는 포함
끝인덱스는 포함하지 않음
즉,
data[0:3]
은 0번부터 3번 전까지 가져오라는 뜻입니다. 그래서 실제로는 인덱스 0, 1, 2만 가져옵니다.
센서 데이터 일부만 확인할 때 유용합니다.
lidar_ranges = [1.2, 1.3, 1.1, 0.9, 0.8, 2.0, 2.1]
front_ranges = lidar_ranges[2:5]
print(front_ranges)
6. 튜플
튜플은 리스트와 비슷하지만 값을 변경할 수 없습니다.
position = (1.0, 2.0, 0.5)
값 접근 방식은 리스트와 같습니다.
x = position[0]
y = position[1]
theta = position[2]
튜플은 보통 좌표, 색상, 고정된 설정값처럼 “변하지 않아야 하는 값”에 사용합니다.
origin = (0.0, 0.0, 0.0)
map_size = (100, 100)
튜플의 값을 바꾸려고 하면 에러가 납니다.
position = (1.0, 2.0)
# position[0] = 3.0
# TypeError 발생
로봇 개발에서는 좌표를 튜플로 반환하는 함수도 자주 볼 수 있습니다.
def get_robot_position():
return 1.2, 3.4, 0.7
x, y, yaw = get_robot_position()
print(x, y, yaw)
7. 딕셔너리
딕셔너리는 key와 value로 데이터를 저장합니다.
robot_config = {
"name": "mobile_robot",
"max_speed": 1.5,
"wheel_radius": 0.05,
"use_lidar": True
}
값을 가져올 때는 key를 사용합니다.
print(robot_config["name"])
print(robot_config["max_speed"])
새 값을 추가할 수도 있습니다.
robot_config["battery_capacity"] = 5000
기존 값을 수정할 수도 있습니다.
robot_config["max_speed"] = 2.0
딕셔너리는 로봇 설정값을 다룰 때 매우 자주 사용합니다.
motor_params = {
"left_motor_id": 1,
"right_motor_id": 2,
"gear_ratio": 30,
"encoder_resolution": 4096
}
안전하게 값을 가져오려면 get()을 사용합니다.
max_speed = robot_config.get("max_speed", 1.0)
min_speed = robot_config.get("min_speed", 0.0)
print(max_speed)
print(min_speed)
get("key", default_value) 형태입니다. 해당 key가 없으면 기본값을 반환합니다.
8. 조건문
조건문은 로봇 상태 판단에 필수입니다.
battery = 35
if battery > 50:
print("Battery is enough")
elif battery > 20:
print("Battery is low")
else:
print("Battery is critical")
로봇에서는 이런 식으로 사용할 수 있습니다.
obstacle_distance = 0.4
if obstacle_distance < 0.5:
print("Stop robot")
else:
print("Move forward")
조건문에서 자주 사용하는 비교 연산자는 다음과 같습니다.
| == | 같다 |
| != | 다르다 |
| > | 크다 |
| < | 작다 |
| >= | 크거나 같다 |
| <= | 작거나 같다 |
예시:
speed = 1.0
if speed == 0.0:
print("Robot stopped")
if speed != 0.0:
print("Robot moving")
9. 논리 연산자
조건을 여러 개 조합할 때 사용합니다.
battery = 80
is_connected = True
if battery > 50 and is_connected:
print("Robot can start")
and는 모든 조건이 참이어야 합니다.
obstacle_distance = 1.2
battery = 70
if obstacle_distance > 0.5 and battery > 30:
print("Move forward")
or는 조건 중 하나만 참이어도 됩니다.
emergency_button = False
obstacle_detected = True
if emergency_button or obstacle_detected:
print("Stop immediately")
not은 참과 거짓을 반대로 바꿉니다.
is_ready = False
if not is_ready:
print("Robot is not ready")
10. 반복문 for
반복문은 여러 데이터를 순서대로 처리할 때 사용합니다.
waypoints = [
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0]
]
for point in waypoints:
print(point)
출력:
[0.0, 0.0]
[1.0, 0.0]
[1.0, 1.0]
좌표를 분리해서 사용할 수도 있습니다.
for point in waypoints:
x = point[0]
y = point[1]
print(f"go to x={x}, y={y}")
더 깔끔하게는 이렇게 작성할 수 있습니다.
for x, y in waypoints:
print(f"go to x={x}, y={y}")
인덱스와 값이 필요하면 enumerate()를 사용합니다.
for index, point in enumerate(waypoints):
print(f"waypoint {index}: {point}")
출력:
waypoint 0: [0.0, 0.0]
waypoint 1: [1.0, 0.0]
waypoint 2: [1.0, 1.0]
11. 반복문 while
while은 조건이 참인 동안 계속 반복합니다.
count = 0
while count < 5:
print(count)
count += 1
로봇 제어 루프와 비슷한 구조입니다.
is_running = True
step = 0
while is_running:
print(f"control step: {step}")
step += 1
if step >= 10:
is_running = False
주의할 점은 무한 루프입니다.
while True:
print("running")
이 코드는 끝나지 않습니다. 실제 로봇 프로그램에서는 종료 조건, 예외 처리, 안전 조건을 반드시 넣어야 합니다.
battery = 100
while battery > 20:
print(f"battery: {battery}")
battery -= 10
print("Low battery. Stop robot.")
12. break와 continue
break는 반복문을 즉시 종료합니다.
sensor_values = [1.2, 1.0, 0.8, 0.3, 0.9]
for distance in sensor_values:
if distance < 0.5:
print("Obstacle detected")
break
print("Safe")
continue는 현재 반복을 건너뛰고 다음 반복으로 넘어갑니다.
sensor_values = [1.2, -1.0, 0.8, -1.0, 0.9]
for distance in sensor_values:
if distance < 0:
continue
print(f"valid distance: {distance}")
센서 값 중 잘못된 값을 무시할 때 유용합니다.
13. 함수
함수는 반복되는 코드를 하나로 묶는 문법입니다.
def say_hello():
print("hello robot")
함수를 실행하려면 호출해야 합니다.
say_hello()
값을 전달할 수도 있습니다.
def print_speed(speed):
print(f"speed: {speed} m/s")
print_speed(1.2)
값을 반환할 수도 있습니다.
def calculate_velocity(distance, time):
return distance / time
velocity = calculate_velocity(10.0, 2.0)
print(velocity)
로봇 개발에서는 계산식을 함수로 분리하는 습관이 중요합니다.
def rpm_to_rad_per_sec(rpm):
return rpm * 2.0 * 3.141592 / 60.0
motor_rpm = 120
angular_velocity = rpm_to_rad_per_sec(motor_rpm)
print(angular_velocity)
14. 기본 인자값
함수 인자에 기본값을 줄 수 있습니다.
def move_robot(speed=0.5):
print(f"move with speed {speed}")
move_robot()
move_robot(1.0)
출력:
move with speed 0.5
move with speed 1.0
로봇 제어 명령에서 기본 속도를 줄 때 유용합니다.
def drive(distance, speed=0.3):
time_required = distance / speed
print(f"drive {distance} m at {speed} m/s")
print(f"estimated time: {time_required:.2f} s")
drive(2.0)
drive(2.0, 0.5)
15. 키워드 인자
함수를 호출할 때 인자 이름을 직접 지정할 수 있습니다.
def set_motor_speed(left, right):
print(f"left={left}, right={right}")
set_motor_speed(left=1.0, right=1.2)
set_motor_speed(right=1.2, left=1.0)
키워드 인자를 쓰면 순서를 헷갈릴 위험이 줄어듭니다.
특히 인자가 많은 함수에서는 키워드 인자가 훨씬 안전합니다.
def set_pid(kp, ki, kd):
print(f"kp={kp}, ki={ki}, kd={kd}")
set_pid(kp=1.0, ki=0.01, kd=0.1)
16. 리스트 컴프리헨션
리스트 컴프리헨션은 리스트를 짧고 깔끔하게 만드는 문법입니다.
일반적인 반복문은 다음과 같습니다.
squares = []
for x in range(5):
squares.append(x * x)
print(squares)
리스트 컴프리헨션으로 바꾸면 다음과 같습니다.
squares = [x * x for x in range(5)]
print(squares)
출력:
[0, 1, 4, 9, 16]
센서 값에 보정값을 적용할 수도 있습니다.
raw_values = [1.0, 1.2, 0.9, 1.1]
offset = 0.05
corrected_values = [value + offset for value in raw_values]
print(corrected_values)
조건을 넣을 수도 있습니다.
ranges = [1.2, -1.0, 0.8, -1.0, 2.0]
valid_ranges = [r for r in ranges if r > 0]
print(valid_ranges)
출력:
[1.2, 0.8, 2.0]
17. range()
range()는 반복 횟수를 만들 때 사용합니다.
for i in range(5):
print(i)
출력:
0
1
2
3
4
시작값과 끝값을 지정할 수 있습니다.
for i in range(1, 6):
print(i)
출력:
1
2
3
4
5
증가값도 지정할 수 있습니다.
for i in range(0, 10, 2):
print(i)
출력:
0
2
4
6
8
제어 루프를 일정 횟수만 테스트할 때 자주 사용합니다.
for step in range(10):
print(f"control step {step}")
18. 예외 처리
로봇 프로그램은 외부 장치, 센서, 파일, 네트워크와 많이 연결됩니다. 이때 에러가 발생할 수 있습니다.
예외 처리를 하지 않으면 프로그램이 바로 종료될 수 있습니다.
value = int("abc")
위 코드는 에러가 납니다.
예외 처리는 try-except를 사용합니다.
try:
value = int("abc")
except ValueError:
print("Cannot convert to integer")
파일을 읽을 때도 예외 처리가 필요합니다.
try:
file = open("config.txt", "r")
content = file.read()
file.close()
except FileNotFoundError:
print("Config file not found")
여러 예외를 처리할 수도 있습니다.
try:
distance = 10.0
time = 0.0
speed = distance / time
except ZeroDivisionError:
print("Time cannot be zero")
except Exception as e:
print(f"Unknown error: {e}")
Exception as e를 사용하면 에러 내용을 확인할 수 있습니다.
19. 파일 읽기와 쓰기
로봇 개발에서는 설정 파일, 로그 파일, 경로 파일, 센서 데이터 파일을 자주 다룹니다.
파일 쓰기:
file = open("robot_log.txt", "w")
file.write("robot started\n")
file.write("battery: 85\n")
file.close()
파일 읽기:
file = open("robot_log.txt", "r")
content = file.read()
file.close()
print(content)
하지만 실제로는 with 문을 사용하는 것이 좋습니다.
with open("robot_log.txt", "w") as file:
file.write("robot started\n")
file.write("battery: 85\n")
with를 사용하면 파일을 자동으로 닫아줍니다.
with open("robot_log.txt", "r") as file:
content = file.read()
print(content)
한 줄씩 읽을 수도 있습니다.
with open("robot_log.txt", "r") as file:
for line in file:
print(line.strip())
strip()은 줄 끝의 개행 문자나 공백을 제거합니다.
20. 모듈과 import: 기능 가져오기
Python은 필요한 기능을 가져와서 씁니다.
import math
angle = math.radians(90)
print(angle)
출력:
1.5707963267948966
자주 쓰는 기본 모듈:
| math | 수학 계산 |
| time | 시간 지연, 시간 측정 |
| random | 랜덤값 |
| os | 파일, 폴더 경로 |
| csv | CSV 파일 처리 |
| json | JSON 파일 처리 |
시간 지연 예제:
import time
print("모터 ON")
time.sleep(1.0)
print("1초 후 모터 OFF")
로봇 제어 루프 예제:
import time
while True:
print("센서 읽기")
print("제어 계산")
print("명령 출력")
time.sleep(0.1)
time.sleep(0.1)은 0.1초 대기입니다.
즉, 대략 10Hz 루프입니다.
'강좌 > ROS2' 카테고리의 다른 글
| VS Code 원격 개발 환경 (0) | 2026.05.24 |
|---|---|
| ROS 2 Humble rqt Plugins 정리 #3 (0) | 2026.05.24 |
| ROS 2 디버깅과 관찰 도구: 로그, rqt_console, rqt_graph, rqt_plot 실습 정리 #2 (0) | 2026.05.24 |
| ROS2 Action Server에 Cancel 기능 추가하기 (0) | 2026.05.23 |
| ROS 2 단위, 좌표, 시간, 파일 시스템, 빌드 시스템, 패키지 구조 정리 #1 (0) | 2026.05.23 |