Exam3 <<
Previous Next >> Webots
Final
Final Report (30%) - 利用網頁內容進行簡報並提交 pdf 格式書面報告, 完成後填回自評表單
參考資料:
cd2025_final_project_w16.7z
three_digit_counter_w16.7z
cd2025_final_project_w17.7z
cd2025_w17_rotate_angle.7z (按下 a 旋轉 -30 deg, 按下 z 旋轉 30 deg)
cd2025_w17_move_and_face.7z (按下 m 先轉向 (3, 3), 前進至 (3, 3) 後面向 (0, 0))
cd2025_w18_move_and_face.7z (按下 j 或 k 可側向移動)
手動投球:
w17.wbt
自動投球:
w17_auto_loop.wbt
counter_supervisor.py
from controller import Supervisor
SEGMENTS = [
[1,1,1,1,1,1,0], # 0
[0,1,1,0,0,0,0], # 1
[1,1,0,1,1,0,1], # 2
[1,1,1,1,0,0,1], # 3
[0,1,1,0,0,1,1], # 4
[1,0,1,1,0,1,1], # 5
[1,0,1,1,1,1,1], # 6
[1,1,1,0,0,0,0], # 7
[1,1,1,1,1,1,1], # 8
[1,1,1,1,0,1,1], # 9
]
DIGIT_MATERIALS = [
['a3mat', 'b3mat', 'c3mat', 'd3mat', 'e3mat', 'f3mat', 'g3mat'], # 百
['a2mat', 'b2mat', 'c2mat', 'd2mat', 'e2mat', 'f2mat', 'g2mat'], # 十
['a1mat', 'b1mat', 'c1mat', 'd1mat', 'e1mat', 'f1mat', 'g1mat'], # 個
]
ON_COLOR = [0, 1, 0]
OFF_COLOR = [0.05, 0.05, 0.05]
def set_digit(supervisor, digit_index, value):
segs = SEGMENTS[value]
for i, seg_on in enumerate(segs):
mat_node = supervisor.getFromDef(DIGIT_MATERIALS[digit_index][i])
if mat_node:
mat_node.getField('diffuseColor').setSFColor(ON_COLOR if seg_on else OFF_COLOR)
else:
print(f"找不到 {DIGIT_MATERIALS[digit_index][i]} 這個DEF")
def set_display(supervisor, value):
value = max(0, min(999, int(value)))
h = value // 100
t = (value // 10) % 10
u = value % 10
set_digit(supervisor, 0, h)
set_digit(supervisor, 1, t)
set_digit(supervisor, 2, u)
supervisor = Supervisor()
timestep = int(supervisor.getBasicTimeStep())
score = 0
receiver = supervisor.getDevice("score_receiver")
receiver.enable(timestep)
while supervisor.step(timestep) != -1:
while receiver.getQueueLength() > 0:
data = receiver.getString()
# 目前 data 接受值包含字串(元) a, m, k 與數字received_score
# 只有接收到數字時才進行得分累加
if data.isdigit():
try:
received_score = int(data)
score += received_score
print(f"收到得分訊息: +{received_score}, 總分: {score}")
except Exception as e:
print("訊息格式錯誤:", e)
receiver.nextPacket()
set_display(supervisor, score)
Robot 與 Supervisor 節點的結合應用: basketball_game_w13.7z 中的 basketball_game.wbt 啟動後直接觸動投籃動作, 並在籃球通過籃框感測器時列出 "得分".
send_command_from_emitter.wbt 啟動後, 由 supervisor 操縱的下列程式送出指令訊號, 交由場景中的 Robot 主體執行:
send_command_from_emitter.py:
from controller import Supervisor
def run_supervisor():
# Create the Supervisor instance
supervisor = Supervisor()
# Get simulation time step
timestep = int(supervisor.getBasicTimeStep())
# Get the emitter for sending commands
emitter = supervisor.getDevice("emitter") # Ensure the emitter is defined in your world file
if emitter is None:
print("Error: Could not find emitter device")
return
# Main control loop
while supervisor.step(timestep) != -1:
# Send motor position command to the robot
motor_position = 38 * 3.14159 / 180 # Motor position in radians
message = f"SET_POSITION:{motor_position}" # Construct the command message
emitter.send(message.encode("utf-8")) # Send the message via the emitter
if __name__ == "__main__":
run_supervisor()
robot_controller.py 中的接收命令程式:
from controller import Robot, Receiver
def run_robot():
# Create the Robot instance
robot = Robot()
# Get simulation time step
timestep = int(robot.getBasicTimeStep())
# Get the motor device
motor = robot.getDevice("motor1") # Replace "motor1" with the actual motor name
if motor is None:
print("Error: Could not find motor device")
return
# Get the receiver for receiving commands
receiver = robot.getDevice("receiver") # Ensure the receiver is defined in your world file
if receiver is None:
print("Error: Could not find receiver device")
return
receiver.enable(timestep)
# Main control loop
while robot.step(timestep) != -1:
# Process received messages
if receiver.getQueueLength() > 0:
message = receiver.getString() # Receive the message
receiver.nextPacket() # Move to the next packet
# Parse the command message
if message.startswith("SET_POSITION:"):
position = float(message.split(":")[1]) # Extract the desired position
motor.setPosition(position) # Set the motor position
if __name__ == "__main__":
run_robot()
此一作法可以利用 supervisor 統整發球機制與投球機構的作動, 例如: 在發球機構啟動之前, 利用 supervisor 模式讓籃球停球在特定位置, 用來控制球拍打後的運動距離.
一旦確定投球機構與球的起始位置之間關係後, 再調整投球機構的持球零件外型設計.
另外, basketball_game_w13_supervisor.wbt 的設計方法, 則僅利用 supervisor 模式負責發球, 之後的擊球機構則完全由 Robot 的 controller 程式控制, 除了啟動場景模擬後的第一次擊球由程式直接控制外, 之後使用者按下 m 鍵機構會回復原始位置, 按下 k 鍵則觸動轉動特定轉角, 按下 a 鍵則由 supervisor 控制程式在特定位置發球.
Exam3 <<
Previous Next >> Webots