Mục lục:

Kỹ thuật viên robot: 8 bước
Kỹ thuật viên robot: 8 bước

Video: Kỹ thuật viên robot: 8 bước

Video: Kỹ thuật viên robot: 8 bước
Video: #Nachi #Robot #Robotics Học lập trình tay máy robot công nghiệp trong 10 phút 2024, Tháng bảy
Anonim
Kỹ thuật viên rô-bốt
Kỹ thuật viên rô-bốt

Hãy tưởng tượng trong một giây rằng bạn là một trong những phi hành gia đáp xuống sao Hỏa. Bạn có hàng triệu việc phải làm, lấy mẫu, chạy thử nghiệm, dữ liệu cần thu thập, nhưng một hoặc hai lần mỗi ngày, bạn cần chạy xung quanh môi trường sống và / hoặc các mô-đun nghiên cứu mà bạn sống và làm việc để kiểm tra chúng. Điều cần thiết của nó, một người nào đó phải đảm bảo rằng mọi thứ ở trạng thái tốt, rằng tất cả hàng nghìn bộ phận và bộ phận đang hoạt động và đúng vị trí. Nhưng điều gì sẽ xảy ra nếu có một người trợ giúp tự động giúp bạn giảm bớt một số nhiệm vụ đó. Điều gì sẽ xảy ra nếu có một con robot nhỏ có thể di chuyển xung quanh bên trong các mô-đun để đảm bảo rằng mọi thứ đều ở đúng vị trí, hoạt động và an toàn.

Kỹ thuật viên Robo đến giải cứu.

Về cơ bản, mã này điều khiển Robo-Technician khi nó đi theo một con đường màu sáng trên mặt đất. Nó sẽ đi theo con đường này cho đến khi nó tìm thấy một điểm giao nhau trong lối đi hoặc một ngã rẽ, điều này sẽ nhắc nhở một bức ảnh được chụp để xử lý hình ảnh để cho phép Kỹ thuật viên rô-bốt đưa ra quyết định về nơi tiếp theo. Cảm biến va chạm nhẹ hoạt động để bảo vệ Kỹ thuật viên rô-bốt khỏi bị hư hại và cảm biến va chạm kiểm soát thời điểm chụp ảnh chẩn đoán. Tất cả cùng nhau, Kỹ thuật viên rô-bốt được thiết kế để phóng to xung quanh các mô-đun của Mar, giải phóng thời gian của các phi hành gia trong khi thực hiện nhiệm vụ cơ bản là kiểm tra, chỉ gọi ý kiến của con người khi phát hiện ra điều gì đó không ổn.

Một lần nữa như một lời cảnh báo, đây là một công việc đang được tiến hành. Mã, khi nó tồn tại, hoạt động nhưng nó gặp trục trặc, đặc biệt là vì có nhiều chương trình chồng chéo liên quan. Ngoài ra, để dự án này hoạt động trong một sứ mệnh sao Hỏa thực sự, một robot sẽ cần được chế tạo cho mục đích cụ thể đó, vì vậy một lần nữa tôi đoán đây là một bản chế tạo "bằng chứng về khái niệm".

Có một số thứ bạn sẽ cần để thiết lập và chạy nó. Bạn sẽ cần một chương trình đắt tiền, các gói hỗ trợ cho chương trình đó và một chút kiến thức nền tảng về mã hóa. Vì tôi là sinh viên và một số mã tầng trệt đã được cung cấp (cho raspberry pi), tôi sẽ không nói cụ thể về cách thiết lập. Bạn có thể tìm thấy tất cả các liên kết cho mã cơ sở đó bên dưới. Hãy đến với danh sách vật liệu.

Phần cứng

  • Raspberry Pi (chúng tôi đã sử dụng phiên bản 3)
  • iRobot ®
  • một số loại thiết bị giữ để giữ Raspberry Pi được gắn vào Robo-Technician
  • Máy ảnh Raspberry Pi (không quan trọng loại nào, miễn là có tiêu cự tự động tốt và độ phân giải hình ảnh)
  • một số loại giá đỡ hoặc bao da để giữ cho máy ảnh hướng về phía trước trên Robo-Technician
  • vật liệu để sử dụng như một dải, màu trắng (hoặc màu rất sáng), được giữ chặt trên sàn. Nó chỉ cần rộng hơn một chút so với không gian giữa hai cảm biến vách đá phía trước.
  • 4 biển báo có chữ rất lớn (có in các từ IMAGE, RIGHT, BACK và LEFT trên chúng)
  • Tờ giấy màu (ít nhất ba tờ và tốt nhất là màu đỏ, xanh lá cây và xanh lam)

Phần mềm

  • Matlab (2018a và 2017b đều được sử dụng và dường như không tạo ra sự khác biệt nhỏ)
  • Gói hỗ trợ Raspberry Pi dành cho Matlab
  • Mã Raspberry Pi để kết nối với Matlab (liên kết đến mã nguồn được cung cấp bên dưới)
  • Hộp công cụ xử lý hình ảnh cho Matlab (bạn hầu như không thể thực hiện dự án này mà không có hộp công cụ)
  • TÙY CHỌN: Matlab Mobile được cài đặt trên điện thoại của bạn, điều này tôi sẽ giải thích sau

Bước 1: Thiết lập phần cứng

ef.engr.utk.edu/ef230-2018-08/projects/roo…

Đây là liên kết cho mã cơ sở để đảm bảo rằng iRobot® có thể giao tiếp với Matlab, cùng với một hướng dẫn cơ bản. Như tôi đã nói trước đây, tôi sẽ không trình bày phần cụ thể này vì hướng dẫn đã được trình bày rất tốt. Tôi sẽ đề cập rằng một khi bạn đã làm theo các bước trên liên kết, bạn có thể sử dụng lệnh "doc" của Matlab để xem qua thông tin được bao gồm. Đặc biệt:

doc roomba

Và một điểm rất quan trọng nữa.

Khi bạn tải xuống các tệp từ liên kết ở trên, hãy ĐĂNG CHÚNG VÀO THƯ MỤC TÔI ĐÃ MÔ TẢ Ở TRÊN, vì Matlab yêu cầu các tệp do người dùng tạo phải nằm trong thư mục làm việc hiện tại.

Với điều đó, chúng ta hãy chuyển sang mã.

Bước 2: Tìm tất cả các cảm biến đó

Tìm tất cả các cảm biến đó
Tìm tất cả các cảm biến đó
Tìm tất cả các cảm biến đó
Tìm tất cả các cảm biến đó

Hãy dành một chút thời gian và kiểm tra iRobot®. Thật tốt khi biết những thứ này ở đâu để bạn có ý tưởng về đầu vào mà Kỹ thuật viên rô-bốt nhận được và bạn sẽ có thể tìm ra lý do tại sao mọi thứ quay theo vòng tròn thay vì đi theo đường dẫn bạn sẽ thiết lập (điều này có thể hoặc có thể đã không xảy ra). Rõ ràng là bạn sẽ thấy cảm biến va chạm vật lý lớn ở mặt trước. Các cảm biến vách đá khó nhìn hơn một chút, bạn sẽ cần lật nó lên và tìm bốn cửa sổ bằng nhựa trong suốt gần mép trước. Các cảm biến va chạm ánh sáng thậm chí còn được ẩn nhiều hơn, nhưng bây giờ sẽ đủ để nói rằng sự sống động trong dải màu đen sáng bóng chạy quanh mặt trước của iRobot®, nằm ở mặt trước của thanh cảm biến va chạm vật lý.

Có các cảm biến rơi bánh xe, nhưng chúng không được sử dụng trong dự án này, vì vậy chúng tôi sẽ chuyển sang thử nghiệm các cảm biến.

Bước 3: Kiểm tra để thiết lập các thông số

Thử nghiệm để thiết lập các tham số
Thử nghiệm để thiết lập các tham số

Trước khi có thể cử Kỹ thuật viên rô-bốt thực hiện công việc đó, chúng tôi cần phải tìm ra các lỗi và phạm vi cảm biến cụ thể của nó. Vì mỗi iRobot® có một chút khác biệt và thay đổi theo vòng đời của robot, chúng tôi cần tìm hiểu cách các cảm biến đọc được các khu vực mà nó sẽ hoạt động. Cách dễ nhất để làm điều này là thiết lập cho bạn đường dẫn màu sáng (Tôi đã sử dụng các dải giấy máy in màu trắng nhưng bất kỳ thứ gì có màu sáng đều sẽ làm được) trên bề mặt mà Kỹ thuật viên Robo sẽ vận hành.

Khởi động Matlab và mở một tập lệnh mới. Lưu tập lệnh TRONG CÙNG THƯ MỤC TÔI MÔ TẢ và đặt tên nó là bất cứ thứ gì bạn muốn (hãy cố gắng giữ nó ngắn gọn, vì tên của tệp này sẽ là tên hàm). Bật robot và sử dụng thiết lập biến roomba từ hướng dẫn, nhập các lệnh vào cửa sổ lệnh.

Đảm bảo Raspberry Pi được cắm vào iRobot® và máy tính của bạn được kết nối với cùng một kết nối internet. Bạn sẽ mất ít thời gian nhổ tóc hơn để tìm hiểu lý do tại sao Matlab không kết nối

r = roomba (số bạn đã thiết lập)

Biến "r" trong trường hợp này là không cần thiết, bạn có thể gọi nó bất cứ thứ gì bạn muốn, nhưng nó giúp cuộc sống dễ dàng hơn khi sử dụng một biến chữ cái.

Sau khi đường dẫn được thiết lập và phòngba đã được kết nối thành công, hãy đặt Kỹ thuật viên rô-bốt tương lai ở vị trí một hoặc hai trong số các cảm biến vách đá ở phía trên đường đi. Rõ ràng điều đó có nghĩa là hai hoặc ba cái còn lại nằm trên bề mặt bạn đã chọn.

Bây giờ khởi động các cảm biến thử nghiệm bằng lệnh:

r.testSensors

Hãy nhớ rằng "r." Là biến bạn đã xác định trước đó, vì vậy nếu nó không phải là 'r', hãy thay đổi 'r.' cho bất cứ điều gì bạn đã quyết định. Thao tác này sẽ hiển thị màn hình cảm biến thử nghiệm với rất nhiều thông tin.

Đối với dự án này, hãy tập trung vào phần cản sáng, phần cản và phần vách đá. Di chuyển Kỹ thuật viên rô-bốt xung quanh để đảm bảo xem các cảm biến thay đổi như thế nào trên các bề mặt khác nhau hoặc mức độ gần của một đối tượng để các giá trị của bộ đệm ligthBumper thay đổi, v.v. Hãy ghi nhớ những con số này (hoặc viết chúng ra) vì bạn sẽ cần họ thiết lập các thông số cho bạn trong một giây.

Bước 4: Bắt đầu mã

Trước hết, bạn sẽ xây dựng một hàm. Tôi đã gọi nó là "con đường" nhưng một lần nữa, cái tên này không cần thiết, nhưng tôi sẽ gọi nó là "con đường" từ bây giờ.

Phần trên cùng của mã là thiết lập một số tùy chọn nhập của người dùng. Nó xây dựng một số danh sách sẽ được sử dụng trong listdlg và sau đó đưa ra một hộp thoại danh sách. Điều này cho phép người dùng chọn màu đường dẫn mà họ muốn đi theo, màu này sẽ phát huy tác dụng sau này.

list = {'Red', 'Blue', 'Green'}

problist = {'Tình trạng, Lưu hình ảnh', 'Thành phần nằm ngoài vị trí, Lưu hình ảnh', 'Dự kiến, Tiếp tục'} pathcolor = listdlg ('PromptString', 'Chọn màu đường dẫn',… 'Chế độ lựa chọn', 'duy nhất', 'ListString', list) prob = 0; nhỏ giọt = ;

Các biến "prob" và "driv" cần được khai báo ở đây vì chúng sẽ được sử dụng bên trong vòng lặp while chính của hàm, nhưng một lần nữa, nếu bạn muốn đổi tên bất kỳ biến nào trong số này hoặc thay đổi lựa chọn danh sách, miễn là bạn nhất quán trong phần còn lại của mã.

Bước 5: Trên cùng của Vòng lặp Trong khi: Cảm biến Bump vật lý

Phần trên cùng của vòng lặp while chứa logic cảm biến va chạm vật lý. Về cơ bản, khi Robo-Technician chạy vào một thứ gì đó, nó sẽ dừng lại (hoặc đối với cảm biến va chạm phía trước, nó lùi lại 0,1 mét), sau đó tự định vị để chụp ảnh. Trước tiên hãy bao gồm phần kiểm soát vận tốc và vị trí.

Nếu bạn đã kiểm tra tất cả các cảm biến trên Robo-Technician ở các bước trước, bạn sẽ biết rằng cảm biến va chạm có giá trị logic (0 hoặc 1) bằng 0 đại diện cho vị trí bình thường, không được nhấn của cảm biến. Hãy ghi nhớ điều đó cho mã.

trong khi true% main while loop% nhận thông tin đệm S = r.getBumpers if S.left ~ = 0 r.stop elseif S.right ~ = 0 r.stop elseif S.front ~ = 0 r.stop end

Đây là phần cơ bản "nếu nó chạm vào thứ gì đó, hãy dừng lại". Nếu các cảm biến phát hiện va chạm, thì nó sẽ chuyển sang phần tiếp theo của mã, phần này sẽ điều chỉnh lại vị trí của Kỹ thuật viên rô-bốt để có được ảnh.

if S.left ~ = 0% if loop lấy thông tin đệm và căn chỉnh máy ảnh cho ảnh r.turnAngle (5) pause (0,5) img = r.getImage% chụp ảnh và hiển thị hộp thoại hình ảnh (img)% prob = listdlg (' PromptString ',' Tìm thấy chướng ngại vật không mong muốn, vui lòng xác định '…,' SelectionMode ',' single ',' ListString ', problist) elseif S.right ~ = 0 r.turnAngle (-5) pause (0,5) img = r. getImage image (img) prob = listdlg ('PromptString', 'Đã tìm thấy chướng ngại vật không mong muốn, vui lòng xác định'…, 'SelectionMode', 'single', 'ListString', problist) elseif S.front ~ = 0 r.moveDistance (- 0,1) pause (0,5) img = r.getImage image (img) prob = listdlg ('PromptString', 'Tìm thấy chướng ngại vật không mong muốn, vui lòng xác định'…, 'SelectionMode', 'single', 'ListString', problist) end

Về cơ bản, một khi hình ảnh được chụp, một hộp thoại khác sẽ xuất hiện với ba tùy chọn. Hai tùy chọn đầu tiên lưu ảnh vào một thư mục cụ thể mà tôi sẽ đề cập sau, trong khi tùy chọn thứ ba chỉ cần đóng hộp thoại và tiếp tục qua vòng lặp. Nếu bạn không thể nhớ các tùy chọn, hãy xem bước trước.

Bây giờ tôi đã chèn một phần mã vào giữa phần cảm biến va chạm và phần lưu ảnh. Điều này lấy giá trị LightBumper và đặt tốc độ truyền động thành 0,025 mét / giây (rất chậm), điều này không thực sự cần thiết nhưng nó làm giảm việc Kỹ thuật viên Robo va chạm vào mọi thứ và cuối cùng làm hao mòn các cảm biến va chạm vật lý.

L = r.getLightBumpers nếu L.left> 100 || L.leftFront> 100 || L.rightFront> 100 || L.right> 100 driv = 0,025 r.setDriveVelocity (0,025) else driv = 0,1 end

Đây sẽ là phần mà các giá trị mà bạn đã quan sát (và hy vọng đã viết ra) trước đó phát huy tác dụng

"L. (cạnh và hướng của cảm biến)> 100" dựa trên các giá trị tôi quan sát được, vì vậy nếu quan sát của bạn khác, hãy thay đổi những con số này. Ý tưởng là nếu Kỹ thuật viên rô-bốt cảm nhận được thứ gì đó cách nó vài cm, nó sẽ chạy chậm lại, nhiều hơn thế là không cần thiết.

Phần tiếp theo là nơi các bức ảnh được lưu để sử dụng sau này.

% nếu tùy chọn đầu tiên hoặc thứ hai được chọn trong hộp thoại prob, lưu hình ảnh nếu prob == 1% if loop xây dựng thông tin tệp cho ảnh, ghi với dấu thời gian t = clock; basename = sprintf ('\ img_% d_% d_% d_% d_% d.png', t (1), t (2), t (3), t (4), t (5)); folder = 'E: / UTK / Classes / fall 18 / ef230 / irobot / images'; fullFileName = fullfile (thư mục, tên cơ sở); imwrite (img, fullFileName) close Hình 1 pause (2) elseif prob == 2 t = clock; basename = sprintf ('\ img_% d_% d_% d_% d_% d.png', t (1), t (2), t (3), t (4), t (5)); folder = 'E: / UTK / Classes / fall 18 / ef230 / irobot / images'; fullFileName = fullfile (thư mục, tên cơ sở); imwrite (img, fullFileName) close Hình 1 tạm dừng (2) end

Tất cả tên tệp và vị trí lưu ảnh đều là tùy chọn. Tôi đã chọn một thư mục được lồng bên trong thư mục roomba mà tôi đã tạo trong bước giới thiệu, nhưng nó có thể ở bất kỳ đâu bạn chọn. Ngoài ra, các bức ảnh được lưu với dấu thời gian, nhưng điều đó không đặc biệt cần thiết (mặc dù theo giả thuyết nó sẽ hữu ích cho một sứ mệnh trên sao Hỏa).

Với các cảm biến va chạm vật lý được che phủ, chúng tôi có thể di chuyển lên các cảm biến vách đá và đường đi theo sau.

Bước 6: Theo đường dẫn

Mã cho cảm biến vách đá được thiết lập để so sánh giá trị của hai giá trị cảm biến phía trước và hai bên. Bạn sẽ cần thay đổi các giá trị này (có thể là) dựa trên các giá trị quan sát của bạn. Bạn cũng có thể cần phải chỉnh sửa các giá trị này sau một vài lần chạy thử nghiệm và thay đổi chúng dựa trên ánh sáng xung quanh, thời gian trong ngày (tùy thuộc vào mức độ ánh sáng của khu vực thử nghiệm) hoặc khi cửa sổ cảm biến bị bẩn.

Tuy nhiên, trước khi chúng ta đi đến mã cảm biến vách đá, có một đoạn mã ngắn mà tôi đã chèn để xóa một số dữ liệu không cần thiết khỏi Matlab. Phần này không cần thiết, nhưng tôi đã sử dụng nó để cắt giảm dung lượng lưu trữ cần thiết để chạy chương trình.

clear img clear t clear basename clear fullFileName clear folder

Đoạn mã tiếp theo là phần thịt của dự án. Nó cho phép Kỹ thuật viên Robo đi theo con đường màu sáng đã được đặt trên sàn. Tóm lại, nó cố gắng tự điều khiển để hai cảm biến vách đá phía trước ở trên ngưỡng, dựa trên các giá trị quan sát của bạn và cho phép chương trình bắt đầu các bước xử lý hình ảnh sau đó một chút.

C = r.getCliffSensors% if vòng lặp theo sau một dải màu (trắng) nếu C.leftFront> 2000 && C.rightFront> 2000% hướng dẫn đường thẳng r.setDriveVelocity (driv) elseif C.leftFront 2000% rẽ phải nếu robot đi quá xa left r.turnAngle (-2,5) elseif C.leftFront> 2000 && C.rightFront <2000% rẽ trái nếu robot đi quá xa phải r.turnAngle (2,5) elseif C.leftFront <2000 && C.rightFront 100 || L.leftFront> 100 || L.rightFront> 100 || L.right> 100 img = r.getImage end% kiểm tra xem có khúc cua trên đường không nếu C.left> 2800 && C.right <2800 r.turnAngle (2.5) elseif C.left 2800 r.turnAngle (- 2.5) end% placeholder dành cho nhận dạng hình ảnh đường dẫn disp ('GETTING IMAGE') end end end end

Hãy nhớ rằng các tên biến tôi đã chọn là tùy chọn, nhưng một lần nữa tôi nghĩ rằng việc sử dụng các biến chữ cái đơn lẻ sẽ giúp cuộc sống dễ dàng hơn khi có thể

Để giải thích phần giữa của mã, khi hai cảm biến phía trước chạy ra khỏi mép của con đường (khi đến giao lộ hoặc khi đến cuối con đường), nó sẽ xem xét liệu có thứ gì đó ở phía trước hay không. Bạn sẽ cần đặt một đối tượng trên mặt đất ở cuối con đường hoặc ở bất kỳ giao lộ nào để đối tượng này hoạt động.

Sau khi chụp ảnh, nó sẽ sử dụng tính năng nhận dạng hình ảnh để tìm ra những việc cần làm. Cũng có một phần giữ chỗ trong phần mã này:

% giữ chỗ cho nhận dạng hình ảnh đường dẫn ('NHẬN HÌNH ẢNH')

Tôi sử dụng điều này vào lúc này vì tôi muốn nói cụ thể về xử lý văn bản và màu sắc xảy ra trong bước tiếp theo.

Bước 7: Xử lý hình ảnh

Có hai phần để xử lý hình ảnh. Đầu tiên là nhận dạng màu sắc, tính toán cường độ màu trong hình ảnh để quyết định có tiếp tục nhận dạng văn bản hay không. Tính toán màu sắc dựa trên lựa chọn được thực hiện trong hộp thoại đầu tiên đó lúc đầu (Tôi đã sử dụng màu đỏ, xanh lam, xanh lục nhưng bạn có thể chọn bất kỳ màu nào bạn muốn, miễn là các giá trị trung bình của cường độ màu có thể được nhận ra bởi Máy ảnh Raspberry Pi).

img = r.getImage img = imcrop (img, [0 30 512 354]) imgb = imcrop (img, [0 30 512 354]) imgt = imcrop (img, [0 30 512 354]) red = mean (mean (imgb (:,:, 1))); g = mean (mean (imgb (:,:, 2))); b = mean (mean (imgb (:,:, 3)));

Đây là kiểm tra cường độ. Điều này sẽ được sử dụng trong phân đoạn tiếp theo để quyết định những gì nó muốn làm.

if red> g && red> b if pathcolor == 1 imgc = imcrop (img, [0 30 512 354]) R = ocr (img) if R. Words {1} == IMAGE || R. AdWords {2} == IMAGE || R. AdWords {3} == IMAGE t = clock; basename = sprintf ('\ img_% d_% d_% d_% d_% d.png', t (1), t (2), t (3), t (4), t (5)); folder = 'E: / UTK / Classes / fall 18 / ef230 / irobot / images'; fullFileName = fullfile (thư mục, tên cơ sở); imwrite (img, fullFileName) pause (2) elseif R. Words {1} == RIGHT || R. AdWords {2} == RIGHT || R. AdWords {3} == RIGHT r.turnAngle (-75) elseif R. AdWords {1} == LEFT || R. AdWords {2} == LEFT || R. AdWords {3} == LEFT r.turnAngle (75) elseif R. AdWords {1} == BACK || R. AdWords {2} == BACK || R. AdWords {3} == BACK r.turnAngle (110) end else r.turnAngle (110) end end

Phân đoạn này quyết định xem màu được chọn trong hộp thoại đầu tiên có khớp với màu mà máy ảnh đang nhìn thấy hay không. Nếu nó chạy, nó sẽ chạy nhận dạng văn bản. Nó sẽ xem từ nào (ẢNH, LẠI, PHẢI hoặc TRÁI) xuất hiện và sau đó quay (cho phải và trái), quay xung quanh (quay lại) hoặc chụp ảnh và lưu nó theo cách tương tự như trước đó.

Tôi chỉ cung cấp một phần mã cho các màu khác nhau

Để cho phép mã nhận dạng màu xanh lam và xanh lục, chỉ cần sao chép mã và thay đổi kiểm tra logic ở đầu đoạn và đặt "pathcolor == (number)" để tương ứng với các lựa chọn màu từ hộp thoại trên cùng (đối với mã khi nó được hiển thị, màu xanh lam sẽ là 2 và màu xanh lá cây sẽ là 3).

Bước 8: Thành phẩm

Thành phẩm
Thành phẩm

Bây giờ Kỹ thuật viên rô-bốt sẽ phóng to xung quanh các mô-đun sứ mệnh trên sao Hỏa và báo cáo lại cho các phi hành gia khi có bất cứ điều gì không đúng vị trí.

Hãy nhớ rằng, tất cả các giá trị của cảm biến vách đá và Bộ đệm ánh sáng cần được thay đổi thành giá trị quan sát của bạn. Ngoài ra, từ kinh nghiệm, tôi thấy tốt hơn nên thử nghiệm dự án này trên sàn màu tối và nó thậm chí còn tốt hơn nếu sàn đó không phản chiếu. Điều này làm cho độ tương phản giữa đường đi và sàn nhà tăng lên, điều này làm cho Kỹ thuật viên rô-bốt đi theo nó một cách chính xác hơn.

Hy vọng bạn thích thiết lập một người trợ giúp nhỏ cho sứ mệnh sao Hỏa và xây dựng vui vẻ.

Đề xuất: