Learning Community

ผลงานวิทยานิพนธ์
ของคุณ พนิต เวชศิลป์
ภาควิชาวิศวกรรมคอมพิวเตอร์
สถาบันเทคโนโลยีพระจอมเกล้าเจ้าคุณทหารลาดกระบัง

ปรับแก้ไขโดยนาย รุ่งโรจน์ โรจนโพธิ์ ( ธันวาคม 2548 )




Learning Community
• Home
• Jini Beginning
- บทเรียนที่ 1
- บทเรียนที่ 2
- บทเรียนที่ 3
- บทเรียนที่ 4
- บทเรียนที่ 5
- บทเรียนที่ 6
- บทเรียนที่ 7
- บทเรียนที่ 8
- บทเรียนที่ 9


บทที่ 7

การออกแบบ Jini Appliction

            จากแนวความคิดของ Jini โครงงานนี้ได้นำแนวคิดและทฤษฎีที่กล่าวมาจากบทข้างต้นมาประยุกต์ใช้ในการสร้างระบบตัวอย่าง ซึ่งระบบนี้จากที่ได้กล่าวไว้ในบทนำ เป็นระบบเครือข่ายของหุ่นยนต์ที่ทำหน้าที่เป็น Service ของ Jini หุ่นยนต์สามารถเชื่อมต่อเข้ากับระบบหรือถอดออกจากระบบได้ตลอดเวลา และสามารถมีหุ่นยนต์ในระบบเพิ่มกี่ตัวก็ได้โดยที่ไม่จำเป็นต้องปรับแต่งระบบ

รูปที่ 7-1 ภาพรวมของการออกแบบระบบ 
            การควบคุมหุ่นยนต์จะควบคุมโดยเครื่องคอมพิวเตอร์มือถือ ปาล์มไพลอต ซึ่งจะทำหน้าที่เป็นผู้ใช้งาน Service ของ Jini Network ซึ่งความสามารถของหุ่นยนต์ที่ถูกควบคุมได้คือ การเดินหน้า ถอยหลัง เลี้ยวซ้าย เลี้ยวขวา และสั่งหยุดการเคลื่อนไหว โดยที่ตัวหุ่นจะมีเซ็นเซอร์ สองชนิด ชนิดละ 1 ตัวติดอยู่ คือ อินฟราเรดเซ็นเซอร์ สำหรับเตือนว่ามีวัตถุขวางอยู่ด้านหน้า และ คอนแท็คสวิตช์ สำหรับแจ้งเตือนการชน หุ่นยนต์จะติดต่อกับ Server ผ่านทางคลื่นอินฟราเรด ซึ่งส่วนที่ใช้ส่งและรับข้อมูลมี Interface แบบ RS-232 ทำให้สามารถใช้สื่อสัญญาณอื่นที่มี Interface แบบ RS-232 แทนอินฟราเรดก็ได้ เช่นสายเคเบิล หรือ คลื่นวิทยุ            เนื่องจากในระบบของ Jini นั้น จะมองบริการทุกอย่างเป็น Service เพราะฉะนั้นในการออกแบบจึงต้องมองภาพของหุ่นยนต์ขนาดเล็กให้อยู่ในรูปของ Service ซึ่งจากการออกแบบ ระบบตัวอย่างนี้จะมองกลุ่มของหุ่นยนต์ขนาดเล็กเป็น 1 Service และรวมเรียก Service นี้ว่า RobotRoomService (ห้องของหุ่นยนต์) โดยแค่ละกลุ่มก็จะมีโปรแกรมที่ทำการสร้าง Service Object และนำไปลงทะเบียนกับ Lookup Service ของ Jini ให้            การออกแบบระบบนี้นั้นสามารถแบ่งการออกแบบ ออกเป็นส่วนต่าง ๆ ได้หลัก ๆ 3 ส่วนคือ ส่วนของปาล์ม ส่วนของ Service (Robot Room Service) และส่วนของฮาร์ดแวร์และซอฟต์แวร์ของหุ่นยนต์ โดยในบทนี้จะกล่าวถึงส่วนของปาล์มและส่วนของ Service ในส่วนของฮาร์ดแวร์และซอฟต์แวร์ของหุ่นยนต์นั้นจะกล่าวถึงในบทถัดไป

7.1 การออกแบบส่วนของ Service

            Service ที่ใช้ในระบบตัวอย่างนี้นั้น แบ่งออกเป็นสองส่วนคือ Service ที่เป็นฮาร์ดแวร์ และ Service ที่เป็นซอฟต์แวร์ ซึ่งมีลักษณะที่แตกต่างกันคือ

  • ซอฟต์แวร์ Service สร้างเป็นโปรแกรมกราฟฟิกซึ่งแสดงห้องของหุ่นยนต์ และมีหุ่นยนต์อยู่ภายในห้อง โดยที่ผู้ใช้สามารถควบคุมหุ่นที่อยู่ในห้องนั้นให้เคลื่อนไหวได้
  • ฮาร์ดแวร์ Service สร้างเป็นหุ่นยนต์ขนาดเล็กควบคุมด้วยไมโครคอนโทรลเลอร์ ผู้ใช้สามารถควบคุมหุ่นให้เคลื่อนที่ได้ และสามารถรับรู้ถึงสถานการณ์ต่าง ๆ ที่เกิดขึ้นจากหุ่นยนต์ จากเซ็นเซอร์ที่ติดอยู่กับตัวหุ่น
โดย Service ทั้งสองรูปแบบนี้ ถึงแม้ว่าจะมีลักษณะที่แตกต่างกัน แต่ว่าถูกสร้างขึ้นมาด้วย Interface เดียวกัน เพราะฉะนั้น การควบคุมจากฝั่งของปาล์มก็จะสามารถทำได้โดยผู้ใช้ไม่รู้สึกถึงความแตกต่าง และไม่จำเป็นต้องปรับแต่งในฝั่งปาล์มแต่อย่างใด

7.1.1 การออกแบบ Service ของ Jini

            กระบวนการในการจะออกแบบและสร้าง Service ของ Jini ไม่ว่าจะเป็นฮาร์ดแวร์ Service หรือซอฟต์แวร์ Service จะมีกระบวนการสร้าง และโครงสร้างหลักของโปรแกรมที่คล้ายกัน จะแตกต่างกันที่รายละเอียด โครงสร้างหลักของ Service สามารถแบ่งได้เป็น 2 ส่วนหลัก ๆ ตามหลักการของการสร้าง Service สำหรับ Jini Network คือ Service Object และตัว Service

            การออกแบบโครงสร้างการทำงานของ Service และ Service Object ผู้พัฒนาระบบนั้นสามารถออกแบบได้หลายแบบ แต่การออกแบบที่ใช้ในโครงงานนี้นั้น ตัว Service จะทำการ สร้าง Service Object ขึ้นมา แล้วทำการลงทะเบียน Service Object นั้นกับ Lookup Service ซึ่งเมื่อผู้ใช้มาค้นหา Service ก็จะได้รับ Service Object เพื่อไปทำหน้าที่เป็นพรอกซี่กลับมายังตัว Service

การสร้าง RobotRoom Service

            การสร้างตัว Service ในโครงงานนี้ตัว Service คือกลุ่มของหุ่นยนต์ซึ่งเราเรียกว่า Room เพราะฉะนั้นจึงสร้างออบเจ็กต์ขึ้นมาเพื่อทำหน้าที่เป็นห้องของหุ่นยนต์ โดยกำหนด Interface ให้กับออบเจ็กต์ที่จะมาสร้างเป็น RoomService เพื่อในกรณีที่ต้องการพัฒนา Service ในรูปแบบต่าง ๆ หลายรูปแบบจะได้สามารถนำ Service แต่ละอันไปใช้ร่วมกันได้โดยผ่าน Interface เดียวกัน

public interface RobotRoom {

       public int[] getAllRobotID();

       public Robot getRobot(int ID);

       public void setSender(ServerDelivery s);

       public void sendEvent(int type,int fromRobot);

       public void display(String s);

}

            ออบเจ็กต์ที่ถูกสร้างเป็น Service นี้นั้นจะทำหน้าที่เป็นผู้ดูแลหุ่นยนต์ที่อยู่ภายในห้อง โดย Method ต่าง ๆ จะถูกเรียกใช้จากผู้ใช้ ผ่านทาง Service Object ออบเจ็กต์ของหุ่นยนต์นั้นก็เช่นกัน จะถูกสร้างตาม Interface ที่ชื่อ Robot

public interface Robot{

       public int getID();

       public void forward();

       public void backward();

       public void turnLeft();

       public void turnRight();

       public void turnOn();

       public void turnOff();

       public void stop_move();

}

            ส่วนการสร้างรายละเอียดของหุ่นยนต์และตัว Service จะสร้างอย่างไรนั้น ก็ขึ้นอยู่กับว่าต้องการให้ Service ออกมาในลักษณะไหน ซึ่งสามารถดูตัวอย่างการสร้างได้ในหัวข้อต่อไป

รูปที่ 7-2 คลาสไดอะแกรม Interface หลักของระบบ 
           Service Object สามารถกล่าวได้ว่าเป็นส่วนที่สำคัญที่สุดของ Service ก็ได้ เนื่องจากการติดต่อกับผู้ใช้ Service นั้นจะต้องทำผ่าน Service Object เพราะฉะนั้น Service Object ที่ออกแบบ ควรจะออกแบบให้ใช้ง่ายสำหรับผู้ใช้

รูปที่ 7-3 คลาสไดอะแกรมของ Service Object  

            จากแผนภาพ UML คลาสที่ทำตัวเป็น Service Object ก็คือ RobotRoomServiceImpl ซึ่งสร้างมาจาก Interface RobotRoomService ซึ่ง Interface นี้มีลักษณะดังนี้

import java.rmi.*;

import net.jini.core.event.*;

public interface RobotRoomService {

    public RobotRoomServiceRegistration getInstance(long duration)

                                         throws RemoteException;

    public EventRegistration trackEvents(long duration,

                                         RemoteEventListener rel,

                                         MarshalledObject key)

                                          throws RemoteException;

}

            เมทตอด getInstance() ใช้สำหรับผู้ใช้ทำการลงทะเบียนเพื่อจะขอใช้ Service โดยถ้าหากลงทะเบียนสำเร็จ จะคืนค่าออกมาเป็นออบเจ็กต์ชนิด RobotRoomServiceRegistration ซึ่งการที่ผู้ใช้ Service จะเรียกใช้ Service ก็จะเรียกผ่านออบเจ็กต์นี้             เมทตอด trackEvents() ใช้สำหรับผู้ใช้ทำการลงทะเบียนเพื่อขอรับฟัง Event ที่เกิดขึ้นในระบบ โดยผู้ใช้จะส่งออบเจ็กต์ที่ทำหน้าที่เป็นตัวดักฟัง Event มาเป็นพารามิเตอร์

สำหรับโครงสร้างของ RobotRoomServiceRegistration คือ

import java.rmi.*;

import net.jini.core.lease.*;

public interface RobotRoomServiceRegistration{

       //Get all RobotID on the room for request control

       public int[] getRobotID() throws RemoteException;

       //Get Robot controller for the specific RobotID

       public RobotController getController(int ID) throws RemoteException;

       //Get the Lease for renewal perpose

       public Lease getLease()  throws RemoteException;

}

เมทตอดที่มีอยู่ 3 อันนั้นมีไว้สำหรับผู้ใช้เพื่อใช้งาน Service เมทตอด getRobotID() ไว้สำหรับเรียกดูว่ามีหุ่นยนต์อยู่กี่ตัวใน Service และมี ID อะไรบ้าง เมทตอด getController ทำหน้าที่ร้องขอออบเจ็กต์ที่ทำหน้าที่ควบคุมหุ่นเมื่อผู้ใช้ต้องการควบคุมหุ่น และเมทตอด getLease() จะคืนค่าเป็น Lease ออบเจ็กต์สำหรับผู้ใช้เพื่อดูแลต่อไป            ใน Service Object (RobotRoomServiceImpl) นั้นจะสร้างออบเจ็กต์ที่ช่วยในการจัดการขึ้นมาอีก 2 ตัวคือ ServerLandlord และ ServerDelivery โดย ServerLandlordสร้างจาก Interface Landlord จากแพคเกจ com.sun.jini.lease.landlord ของชุดพัฒนา Jini ซึ่ง ServerLandlord ทำหน้าที่เป็นตัวสร้างและดูแล Lease ออบเจ็กต์ของผู้ใช้ คอยดูแลว่า Lease ใดไม่ได้ถูกผู้ใช้ Renew ตามเวลาที่กำหนด ก็จะทำให้ Lease นั้นหมดอายุและถือว่าผู้ใช้ที่เป็นเจ้าของ Lease นั้นได้ออกจากระบบไปแล้ว Service Object ที่สร้างขึ้นมานี้สามารถนำไปใช้ได้กับทั้งฮาร์ดแวร์ Service และซอฟต์แวร์ Service เนื่องจาก Service Object นี้นั้นติดต่อกลับมายังตัว Service ผ่าน Interface RobotRoom และตัว Service ทั้งฮาร์ดแวร์ Service และซอฟต์แวร์ Service ต่างก็ต้องสร้างมาจาก Interface นี้ด้วย จึงทำให้สามารถใช้ Service Object นี้ร่วมกันได้            ServerDelivery ทำหน้าที่ส่ง Event ไปยังผู้ใช้ที่มาลงทะเบียนรับฟัง Event ไว้โดยออบเจ็กต์นี้จะถูกเรียกใช้จาก RobotRoom เพื่อส่ง Event ที่เกิดจากหุ่นยนต์

7.1.2 การออกแบบซอฟต์แวร์ Service (Robot Simulator)

            การออกแบบโปรแกรมโรบอตซิมมูเลเตอร์ หรือเรียกย่อๆว่า RobotSim นั้นจะออกแบบโปรแกรมในลักษณะโปรแกรมกราฟฟิกที่แสดงห้องของหุ่นยนต์ โดยห้องนั้นมีกำแพงล้อมรอบ และมีวัตถุเสมือนวางอยู่ภายในห้อง โปรแกรมนี้จะลงทะเบียนตัวเองเป็นซอฟต์แวร์ Service ของ Jini

รูปที่ 7-4 ตัวอย่างหน้าจอของโปรแกรมโรบอตซิมมูเลเตอร์ 
            จากที่ได้กล่าวมาข้างต้น การสร้าง Service ที่แตกต่างกัน สามารถทำได้โดยการสร้างจาก Interface เดียวกัน คือ RobotRoom และ Robot ซึ่งผู้พัฒนาสามารถเพิ่มส่วนที่เป็นรายละเอียดเข้าไปได้ สำหรับ โรบอตซิมมูเลเตอร์ มีการออกแบบคร่าวๆดังนี้

รูปที่ 7-5 คลาสไดอะแกรมของโปรแกรมโรบอตซิมมูเลเตอร์

            คลาส RobotSim ซึ่งเป็นคลาสหลักของ Service นี้ ทำการสร้างออบเจ็กต์ RobotRoomSim (สร้างจาก Interface RobotRoom) เพื่อเป็นตัว Service และสร้าง RobotImpl (สร้างจาก Interface Robot) ซึ่งแทนตัวหุ่นยนต์จำลองในระบบนี้ โดยการแสดงผลห้องของหุ่นยนต์ที่เป็นกราฟฟิกนั้นจะแสดงผลโดยออบเจ็กต์ของคลาส DisplayFrame ซึ่ง Inherit มาจากคลาส Frame DisplayFrame นั้นจะทำการอ่านค่าตำแหน่งของหุ่นยนต์จำลองที่อยู่ภายในห้อง ตำแหน่งของออบเจ็กต์ต่าง ๆ ภายในห้อง แล้วทำการนำมาแสดงผลในรูปแบบของกราฟฟิก

            ออบเจ็กต์ RobotRoomServiceImpl สร้างขึ้นมาโดยกำหนดให้เป็น ออบเจ็กต์ระยะไกล เพื่อทำหน้าที่เป็น Service Object RobotSim จะทำการลงทะเบียน Service Object นี้กับ ลุคอัพ Service โดยออบเจ็กต์ของคลาส JoinManager ซึ่งเป็นส่วนหนึ่งของชุดพัฒนา Jini

7.1.3 การออกแบบฮาร์ดแวร์ Service

            ฮาร์ดแวร์เซอวิสในโครงงานนี้นั้นจะสร้างเป็นตัวหุ่นยนต์ขนาดเล็กซึ่งควบคุมด้วยไมโครคอนโทรลเลอร์ตระกูล 8051 การเขียนโปรแกรมควบคุมหุ่นยนต์นั้นใช้ภาษาแอสเซมบลีสำหรับ 8051 ในการเขียน ทำให้หุ่นยนต์ที่สร้างขึ้นยังไม่มีความสามารถที่จะติดต่อกับเครือข่ายของ Jini ได้โดยตรง จึงจำเป็นต้องมีการพัฒนาโปรแกรมเพิ่มเติม เพื่อเป็นตัวกลางในการติดต่อระหว่างหุ่นยนต์และเครือข่ายของ Jini โดยให้ชื่อโปรแกรมว่า โรบอตเดมอน (Robot Daemond)            เนื่องจากตามหลักการและแนวคิดของ Jini ที่ทำให้อุปกรณ์ต่าง ๆ ต่อเชื่อมเข้ากับเครือข่ายได้อย่างอัตโนมัตินั้น การพัฒนาโปรแกรมโรบอตเดมอนนั้นจึงสร้างให้มีความอัตโนมัติมากที่สุด โดยถึงแม้ว่าจะไม่ได้ใช้ความสามารถของ Jini แต่ก็ใช้หลักการเดียวกันในการสร้าง            การออกแบบฮาร์ดแวร์ Service นี้นั้นจะแบ่งการออกแบบเป็นสองส่วน คือส่วนของโปรแกรมโรบอตเดมอน และส่วนของตัวฮาร์ดแวร์ของหุ่นยนต์ ซึ่งส่วนของโปรแกรมโรบอตเดมอนนี้นั้นจะกล่าวถึงในบทนี้ ส่วนตัวฮาร์ดแวร์ของหุ่นยนต์นั้น จะกล่าวถึงในบทถัดไป             การติดต่อกันระหว่างฮาร์ดแวร์ของหุ่นยนต์กับโปรแกรมโรบอตเดมอนนั้น จะสร้างโพรโตคอลในการคุยกัน ดังนี้
  • การส่งข้อมูลในแต่ละครั้งระหว่างโรบอตเดมอนไปยังหุ่นยนต์ และระหว่างหุ่นยนต์มายังโรบอต-เดมอนจะส่งข้อมูลทีละ 1 ไบต์ โดยลักษณะของ แมสเซจและการแบ่งเป็น message ประเภทต่าง ๆ ดังนี้

Message จากหุ่นยนต์ à โรบอตเดมอน

          PING                  มีโครงสร้างคือ

          ALERT_HIT        มีโครงสร้างคือ

          HIT_UNKNOWN มีโครงสร้างคือ

Message จากโรบอตเดมอน à หุ่นยนต์

          ROBOT_FORWARD       มีโครงสร้างคือ

          ROBOT_BACKWARD     มีโครงสร้างคือ

          ROBOT_LEFT                มีโครงสร้างคือ

          ROBOT_RIGHT              มีโครงสร้างคือ

          ROBOT_STOP               มีโครงสร้างคือ

ใน 3 บิตหลังจะแทนค่าด้วยหมายเลข ID ของหุ่นยนต์ที่เกี่ยวข้อง เป็นเลขฐานสอง ซึ่งแสดงว่าระบบนี้สามารถมีหุ่นยนต์ได้พร้อมกันทีละ 16 ตัวโดยมี ID คือ 0-15 หากต้องการพัฒนาให้รองรับหุ่นยนต์ให้ได้มากกว่า 16 ตัวจะต้องมีการแก้ไขในส่วนโพรโตคอลการสื่อสารใหม่

  • หุ่นยนต์จะใช้ message PING ในการบอกกับระบบว่าตอนนี้ได้เชื่อมต่อกับระบบแล้ว
  • หุ่นยนต์จะต้องส่ง message PING มายังโรบอตเดมอนภายในเวลาที่กำหนด มิเช่นนั้นโรบอตเดมอนจะถือว่าหุ่นยนต์ตัวนั้นออกจากระบบไปแล้ว (ไทม์เอ้าท์)
  • เมื่อเกิดเหตุการณ์อะไรขึ้นกับหุ่นยนต์ หุ่นยนต์จะแจ้งให้กับระบบทราบโดยใช้ message ALERT_HIT และ HIT_UNKNOWN
  • โรบอตเดมอนจะส่งสัญญาณควบคุมเพื่อควบคุมไปยังหุ่นด้วยสัญญาณ ROBOT_FORWARD ROBOT_BACKWARD,ROBOT_LEFT,ROBOT_RIGHT,ROBOT_LEFT และ ROBOT_STOP และใส่หมายเลข ID ของหุ่นที่ต้องการควบคุมไปยัง 3 บิตหลัง
  • เมื่อโรบอตเดมอนได้รับสัญญาณปิงในครั้งแรกจากหุ่นยนต์ตัวใด จะถือว่าหุ่นยนต์ตัวนั้นได้เข้าสู่ระบบ หุ่นยนต์ตัวนั้นจะต้องส่งสัญญาณ PING มาเรื่อยๆเพื่อยืนยันการคงอยู่ของตนเอง ถ้าหากหุ่นยนต์ไม่ได้ส่งสัญญาณ PING กลับมายังระบบภายในเวลาที่กำหนดไว้ จะถือว่าหุ่นยนต์ตัวนั้นได้ออกจากระบบแล้ว ซึ่งแนวคิดนี้ได้นำมาจากกระบวนการ Leasing ของ Jini การ PING ก็เปรียบเสมือนการ renew Lease นั่นเอง

7.1.4 การออกแบบโปรแกรมโรบอตเดมอน

            โปรแกรมนี้จะสร้างเป็นโปรแกรมที่ใช้ควบคุมหุ่นยนต์ที่เป็นฮาร์ดแวร์โดยการส่งสัญญาณการควบคุมผ่านไปทางพอร์ต COM ซึ่งการติดต่อไปยังพอร์ตการสื่อสารนั้น จะใช้ชุด API พิเศษของภาษาจาวาชื่อว่า Java Communication API ซึ่งสามารถใช้ในการติดต่อกับพอร์ตการสื่อสารของคอมพิวเตอร์ได้

            โรบอตเดมอนสามารถติดต่อกับหุ่นยนต์ได้ทีละหลายตัวผ่านทางพอร์ตอนุกรมเพียงพอร์ตเดียว ด้วยการเปลี่ยนสื่อสำหรับการส่งข้อมูลออกจากพอร์ตอนุกรมไปยังหุ่นยนต์ ซึ่งในโครงงานนี้ได้ใช้การสื่อสารด้วยอินฟราเรด มาเป็นตัวกลางในการส่งข้อมูลระหว่างคอมพิวเตอร์และหุ่นยนต์ ทำให้สามารถกระจายสัญญาณจากตัวโรบอตเดมอนไปยังหุ่นยนต์ได้ทีละหลายตัว

            การออกแบบโปรแกรมสามารถแสดงได้ด้วยแผนภาพ UML อย่างคร่าวๆได้ดังนี้

รูปที่ 7-6 คลาสไดอะแกรมของโปรแกรมโรบอตเดมอน

            ตัว Service นั้นคือออบเจ็กต์ที่ทำหน้าที่เป็นห้องเสมือนของหุ่นยนต์ คือ RobotRoomImpl ซึ่งสร้างมาจาก Interface RobotRoom ส่วน Service Object นั้นสามารถใช้ออบเจ็กต์ชนิดเดียวกับที่เป็นซอฟต์แวร์ Service คือ RobotRoomServiceImpl ได้เลยเนื่องจากว่า Service Object นี้นั้นติดต่อกลับมายังตัว Service ผ่าน Interface RobotRoom และตัว Service สำหรับฮาร์ดแวร์ Service นี้นั้นก็สร้างมาจาก Interface นี้ด้วย จึงทำให้สามารถใช้ร่วมกันได้            RobotRoomImpl ซึ่งเป็นตัว Service นั้นจะสร้างออบเจ็กต์ที่มาช่วยในการจัดการหุ่นอีก 3 ตัวคือ PortManager ทำหน้าที่ดูแลรับและส่งข้อมูลจากพอร์ตสื่อสาร MessageProcessor ทำหน้าที่ประมวลผลข้อมูลที่รับมาจาก PortManager และสุดท้าย RobotManager ทำหน้าที่เป็นตัวจัดการกับหุ่นยนต์แต่ละตัว โดยจะทำงานกับหุ่นยนต์เสมือน ที่สร้างขึ้นจากออบเจ็กต์ RobotProxy RobotProxy นั้นถูกสร้างขึ้นมาตาม Interface Robot ทำให้สามารถทำงานร่วมกับ Service Object ได้เป็นอย่างดี            เมื่อมีสัญญาณ PING เข้ามายังพอร์ต MessageProcessor จะแจ้งให้กับ RobotManager ทราบว่ามีสัญญาณ PING มาจากหุ่นยนต์ ID ใด เมื่อ RobotManager ทราบก็จะไปตรวจสอบดูว่ามี RobotProxy ถูกสร้างขี้นมาสำหรับหุ่นยนต์ ID นั้นหรือยัง ถ้ายัง ก็จะสร้าง RobotProxy สำหรับหุ่นยนต์ ID นั้นขึ้นเพื่อแสดงว่าหุ่นยนต์ที่มี ID ที่ส่งมานั้นได้เชื่อมต่อกับระบบแล้ว ถ้าหากว่ามี RobotProxy สำหรับหุ่นยนต์ ID นั้นอยู่แล้ว RobotManager ก็จะถือว่าเป็นสัญญาณการ renew ของ RobotProxy

            และ RobotManager ยังสร้างเธรดขึ้นมาอีกเธรดหนึ่งเพื่อเป็นตัวตรวจสอบว่า RobotProxy ตัวใดหมดอายุแล้ว ถ้าหากตัวใดหมดอายุ ก็จะถอดหุ่นยนต์ตัวนั้นออกจากระบบ

            สำหรับโปรแกรมนี้ได้มีการสร้าง GUI ขึ้นมาด้วยเพื่อให้ผู้ใช้งานระบบได้ใช้ในการปรับแต่งค่าต่าง ๆ ของ Service เนื่องจากการสื่อสารผ่านพอร์ตอนุกรมจะต้องมีการกำหนดค่าพารามิเตอร์ต่าง ๆ เพื่อจะเปิดพอร์ตในการติดต่อสื่อสาร

รูปที่ 7-7 ตัวอย่างหน้าจอของโปรแกรมโรยอตเดมอน


             ค่าที่สามารถปรับแต่งได้สำหรับ Service คือ
  • ชื่อของ Service ที่ลงทะเบียนกับ Jini
  • ตัองการรับข้อมูลที่พอร์ตไหน
  • มี baud rate เท่าใด
  • ระยะเวลาช่วงอายุของ RobotProxy ถ้าไม่ได้รับการ รีนิว
  • ช่วงเวลาการตรวจสอบหา RobotProxy ของหุ่นยนต์ที่หมดอายุ

7.2 การออกแบบในส่วนของผู้ใช้

7.2.1 การออกแบบโปรแกรมบนปาล์ม


            ผู้ใช้ของ Service นั้นจะควบคุมหุ่นยนต์โดยผ่านเครื่องปาล์ม ซึ่งเครื่องปาล์มนั้นจะมีโปรแกรมที่ทำหน้าที่เป็นเหมือนคันบังคับของหุ่นอยู่ โปรแกรมนี้จะถูกเขียนขึ้นด้วยภาษาจาวาและทำงานอยู่บน เวอร์ชวลมาชีน สำหรับเครื่องปาล์มโดยเฉพาะที่ชื่อว่า KVM ย่อมาจาก Kilobyte Virtual Machine ซึ่งเป็นส่วนหนึ่งของ จาวาไมโครอดิชันเวอร์ชัน 2 ซึ่งรายละเอียดเกี่ยวกับ KVM รวมถึงวิธีการเขียนโปรแกรมสำหรับปาล์มนี้สามารถดูได้ในภาคผนวก  

            ด้านบนนี้คือภาพหน้าจอของโปรแกรมควบคุมหุ่นยนต์สำหรับปาล์ม ซึ่งประกอบด้วยส่วนต่าง ๆ ที่ใช้ในการควบคุมหุ่นยนต์ดังนี้

  • ปุ่มควบคุมการทำงานของระบบ มีปุ่ม Connect ใช้ในการเชื่อมต่อเข้ากับ PalmDaemond ปุ่ม Disconnect ใช้เลิกการติดต่อกับ PalmDaemond ปุ่ม Exit ใช้ออกจากโปรแกรม และปุ่ม Find Service ใช้ค้นหา Service เมื่อเชื่อมต่อกับระบบอยู่
  • ปุ่มควบคุมทิศทางของหุ่นยนต์ ใช้สำหรับควบคุมทิศทางของหุ่น เมื่อเลือกตัวหุ่นที่จะบังคับแล้ว
  • ปุ่มตัวเลขเอนกประสงค์ ใช้ช่วยในสถานะต่าง ๆ ของโปรแกรม เช่น ในเวลาการค้นหา Service ก็จะใช้เลือก Service ที่ต้องการเมื่อค้นหาพบ
  • หน้าจอแสดงผลข้อมูลจาก Server แสดงผลข้อมูลและข้อความที่ส่งมาจาก Server
  • แถบแสดงสถานะของโปรแกรม แสดงสถานะของโปรแกรมในขณะนั้น
แต่จากการศึกษาพบว่า ไม่สามารถให้โปรแกรมสำหรับปาล์มเชื่อมต่อกับระบบของ Jini ได้โดยตรงเนื่องมาจาก ชุด API ของ Java2MicroEdition ซึ่งเป็น API สำหรับปาล์มนั้นไม่มีส่วนของ Java RMI ซึ่งเป็นส่วนประกอบสำคัญที่ใช้ในการติดต่อกับระบบเครือข่ายของ Jini ทำให้ต้องมีการพัฒนาโปรแกรมเพิ่มเติม เพื่อทำให้ปาล์มสามารถทำงานกับเครือข่ายของ Jini ได้ โดยที่โปรแกรมที่พัฒนาเพิ่มเติมนั้น จะทำการสร้างออบเจ็กต์ที่ทำตัวเป็นเหมือนพรอกซี่ (Proxy) ของปาล์มแต่ละเครื่องที่เชื่อมต่อเข้ามาในระบบ ซึ่ง พรอกซี่นั้นทำหน้าที่ในการเชื่อมต่อไปยังเครือข่ายของ Jini โปรแกรมนี้ชื่อว่าปาล์มเดมอน (PalmDaemon)

รูปที่ 7-8 ตัวอย่างหน้าจอของโปรแกรมโรยอต Client

7.2.2 การออกแบบปาล์มเดมอน

            เครื่องปาล์มจะเชื่อมต่อกับปาล์มเดมอนผ่านทางโพรโตคอล TCP/IP โดยสร้างซ๊อกเก็ตมายังโปรแกรมปาล์มเดมอน ซึ่งนั้นจะทำงานอยู่บนเครื่องพีซีที่มีพลังการประมวลผลสูงกว่า ทำให้สามารถใช้ Java RMI ของ Java 2 Standard Edition ได้ โดยปาล์มเดมอนนั้นจะทำการสร้างออบเจ็กต์ ที่มีลักษณะเป็นพรอกซี่ซึ่งเป็นเหมือนตัวแทนของปาล์มในการเชื่อมต่อไปยังระบบเครือข่ายของ Jini


  รูปที่ 7-9 การออกแบบโปรแกรมปาล์มเดมอน

 
            การคุยกันระหว่างปาล์มและปาล์มเดมอนหลังจากที่ปาล์มเดมอนทำการสร้างพรอกซี่ออบเจ็กต์ที่ชื่อปาล์มพรอกซี่ (PalmProxy) แล้ว ซอกเก็ตของปาล์มจะถูกโอนมาให้ปาล์มพรอกซี่ดูแลต่อ การทำงานของปาล์มพรอกซี่จะรับข้อมูลคำสั่งมาจากปาล์มโดยเมื่อมีการกดปุ่มใด ๆ บนหน้าจอของปาล์มจะมีการส่งคำสั่งของปุ่มนั้นมาเป็นสตริง ให้กับปาล์มพรอกซี่ โดยที่ปาล์มพรอกซี่จะนำคำสั่งที่ส่งมามาประมวลผลตามสเตทต่าง ๆ ของปาล์มพรอกซี่ คำสั่งต่าง ๆ ที่ส่งมาจากการกดปุ่มคือ

ลูกศรบังคับทิศทาง ขึ้น           ส่งข้อมูล             “up”

ลูกศรบังคับทิศทาง ลง            ส่งข้อมูล             “down”

ลูกศรบังคับทิศทาง ซ้าย          ส่งข้อมูล             “left”

ลูกศรบังคับทิศทาง ขวา          ส่งข้อมูล             “right”

ปุ่มวงกลมตรงกลาง               ส่งข้อมูล             “stop”

ปุ่ม Find Service                  ส่งข้อมูล             “find service”

ปุ่ม !                                   ส่งข้อมูล             “turn on”

ปุ่ม ?                                  ส่งข้อมูล             “turn off”


เสตทต่าง ๆ ของปาล์มพรอกซี่ สามารถเขียนอธิบายได้ด้วย State Diagram ของ UML ได้คือ

รูปที่ 7-10 สเตทไดอะแกรมของออบเจ็กต์ปาล์มพรอกซี่

้วและปาล์มพรอกซี่ถูกสร้างขึ้น จากนั้นซ๊อกเก็ตของปาล์มจะถูกส่งมาให้กับปาล์มพรอกซี่ดูแล เมื่อผู้ใช้กดปุ่ม Find service คำสั่ง “find service” ก็จะถูกส่งไปยังปาล์มพรอกซี่ ปาล์มพรอกซี่จะสร้างออบเจ็กต์ ServiceFinder ขึ้นมา โดย ServiceFinder จะทำการค้นหา ลุคอัพ Service จากในเครือข่ายด้วยวิธีการทำ Multicasting เมื่อ ServiceFinder ค้นพบ Lookup Service แล้วก็จะทำการค้นหา Service ที่มี Interface ตรงกับ Service ที่ปาล์มต้องการคือ RobotRoomService ซึ่งมี Interface ดังนี้

import java.rmi.*;

import net.jini.core.event.*;

public interface RobotRoomService {

    public RobotRoomServiceRegistration getInstance(long duration)

                                         throws RemoteException;

    public EventRegistration trackEvents(long duration,

                                         RemoteEventListener rel,

                                         MarshalledObject key)

                                          throws RemoteException;

}

            ServiceFinder จะคืนค่าจากการค้นหา Service เป็นอาร์เรย์ของ Service Object ของ Service ที่ตรงตามความต้องการ    เมื่อปาล์มพรอกซี่ค้นหา Service ที่ตรงกับความต้องการพบ ก็จะแจ้งให้กับปาล์มทราบว่าพบ Service จำนวนกี่ตัวและมีชื่อว่าอะไรบ้างโดยอ่านค่าชื่อของ Service มาจาก Service Object จากนั้นปาล์มพรอกซี่ก็จะเปลี่ยนเสตทไปเป็น WAIT_FOR_SERVICE_ID เพื่อที่จะรอให้ผู้ใช้กดปุ่มตัวเลขเพื่อเลือก Service ที่ต้องการ    เมื่อผู้ใช้เลือก Service ที่ต้องการแล้วปาล์มพรอกซี่ก็จะทำการติดต่อกับตัว Service โดยตรงโดยทำผ่าน Service Object ที่มีอยู่ กระบวนการที่ปาล์มพรอกซี่ติดต่อกับ Service เพื่อจะเตรียมการในการบังคับหุ่นยนต์มีดังนี้
  1. ร้องขอ Registeration ออบเจ็กต์จาก Service ด้วย เมธอด getInstance() ของ Service Object โดยส่ง duration time ของ Lease ที่ต้องการให้กับ Method นี้ ออบเจ็กต์ที่คืนค่ามาจะมีชนิดเป็น RobotRoomServiceRegistration ซึ่งจะมี Lease ของ Service นี้ติดมากับ Registration ออบเจ็กต์ด้วย สามารถเรียกใช้ได้จาก เมธอด getLease() โดยปาล์มพรอกซี่ จะนำ Lease ที่ได้จาก RobotRoomServiceResistration ไปส่งให้ LeaseRenewalManager เป็นผู้ดูแล
  2. ลงทะเบียนขอรับ Event จาก Service โดย เมธอด trackEvents() ของ Service Object โดยส่งพารามิเตอร์ให้กับ Method นี้ 3 ตัวคือ duration time ของ Lease ของการรับฟัง Event ที่ต้องการ, ออบเจ็กต์ที่ทำหน้าที่เป็นตัวดักฟังเหตุการณ์ทางไกล (Remote Event Listener) และ Marshalled Object ซึ่งอาจส่งค่าเป็น null ให้ไปก็ได้ การลงทะเบียนนี้จะคืนค่ามาเป็นออบเจ็กต์ที่มีชนิดเป็น EventRegistration ซึ่งจะมี Lease ของการรับฟัง Event ติดมาด้วย โดยสามารถเรียกใช้ได้จาก เมธอด getLease() และส่งต่อให้กับ LeaseRenewalManager เป็นผู้ดูแล
  3. ทำการตรวจดูว่ามีหุ่นยนต์ลงทะเบียนอยู่กี่ตัวใน Service นั้นด้วย เมธอด getRobotID() ของ RobotRoomServiceRegistration ออบเจ็กต์ ซึ่งจะคืนค่ามาเป็นอาร์เรย์ของ ID ของหุ่นยนต์ทั้งหมดใน Service แล้วทำการแสดงผลให้กับผู้ใช้ทราบ
  4. เปลี่ยนเสตทของปาล์มพรอกซี่เป็น WAIT_FOR_ROBOT_ID เพื่อรอรับการเลือกหุ่นที่จะบังคับจากผู้ใช้
  5. เมื่อผู้ใช้กดปุ่มตัวเลขเพื่อเลือกว่าจะควบคุมหุ่นยนต์ตัวไหนแล้ว ปาล์มพรอกซี่ก็จะทำการร้องขอ ออบเจ็กต์ที่ใช้ในการควบคุมหุ่น (RobotController) โดยใช้ เมธอด getController() จาก RobotRoomServiceRegistration โดยส่งพารามิเตอร์ให้คือ ID ของหุ่นเพื่อจะเลือกว่าจะควบคุมหุ่นตัวใด ออบเจ็กต์นี้เป็นออบเจ็กต์ระยะไกล ซึ่งตัวออบเจ็กต์จริงๆนั้นจะทำงานอยู่ที่ฝั่ง Service หลังจากที่ได้ออบเจ็กต์นี้มาแล้ว ปาล์มพรอกซี่ก็จะเปลี่ยนสถานะเป็น WAIT_FOR_CONTROL เพื่อรอรับการกดปุ่มทิศทางจากฝั่งของปาล์ม
  6. การบังคับหุ่นยนต์จะใช้การเรียกใช้ Method ของโรบอตคอนโทรลเลอร์ เช่นเมื่อฝั่งปาล์มกดปุ่มลูกศรขึ้น ปาล์มก็จะส่ง “up” มาให้กับปาล์มพรอกซี่  เมื่อปาล์มพรอกซี่รับคำสั่งมาแล้วก็จะมาแปลว่าเป็นคำสั่งอะไร ถ้าหากพบว่าเป็นคำสั่ง “up” ก็จะทำการเรียกใช้ เมธอด forward() ของโรบอตคอนโทรลเลอร์ เพื่อสั่งให้หุ่นยนต์เดินไปข้างหน้า





Last update : June 17, 2009 17:00 ( Thailand )

Apple, Mac, iMac, iPhone and iPod are trademarks of Apple, Inc.

Jini, Java and all Java-based are trademarks of Sun Microsystems, Inc.



JiniSoft Corporation

Copyright @ 1990 - 2009   Mr. Roongroj Rojanapo ( )

99/2 Soi Ramindra 14, Ramindra Road, Bangkane, Bangkok 10230, Thailand


E-mail : roongroj @ mac.com
SMS : 081 615-5135  ( iPhone )
FAX : 02   943-6433