ç§ã®é·å¹Žã®ã€ã®ãªã¹ã®ããŒãããŒïŒ2幎åã«åœŒã«
å®ãŠããéµéå
äœæã®èªèã ïŒã¯ãããžãã¹ããã»ã¹ãæé©åããããã®æ°ããã¢ã€ãã¢ãæã£ãŠããŸããã ãã¡ããããã€ã³ãã¯ãããŒããŒããã¹ãŠã®ããããã®åŸãã«ç¶ããããããã忢ãããšããã«ããŒããšã¢ã³ããŒããéå§ããããšã§ã¯ãããŸããããããŒããŒãããã¯ããã«å€ãã®ããããããããã»ãšãã©ã®å Žåããããã¯ãšã³ããã€ã³ãã«ãããŸãã«ãŒããããŒãåŸ
ã¡ã ããŒããŒã¯ãããããããããæ¬¡ã®ããããã«ç§»åãããããããããŒãããã ãã§ãååã®èŒžéã«æéãæµªè²»ããŸããã
èæ¯

æšå¹Žãã«ã³ãã®èªèµ°åŒæé€æ©ãã©ãããã©ãŒã ãå®éšããŸããã æ°åã®æé€æ©ã®è²»çšã¯çŽ300ãã³ãïŒäœ¿çšæžã¿ã®ãã®ã¯100ãã³ããŸãã¯ãã以äžïŒã§ãããè»èŒªã«2å°ã®é»æ°é§åè£
眮ãåé¢ã«2å°ã®ã¿ããã»ã³ãµãŒãäžéšã«ïŒæé ãæ€åºããããïŒããã³äžéšã«ïŒç匟ã¹ããŒã·ã§ã³ãèŠã€ããããã«ïŒèµ€å€ç·ã»ã³ãµãŒãå«ãŸããŠããŸãã ã»ã³ãµãŒã®æ£ç¢ºãªãªã¹ãã¯ã¢ãã«ã«ãã£ãŠç°ãªããŸãããããã³ã«ã¯ãäžããæå€§4ã€ã®èµ€å€ç·ã»ã³ãµãŒãæäŸããããããã1ããããè¿ããŸãïŒãåºãèŠãã/èŠããªããïŒã ãããã«ãããè·é¢èšã¯ãããŸãããå©çšå¯èœãªã»ã³ãµãŒã¯ãã¹ãŠã·ã³ã°ã«ãããã§ãã ããã«ãRoombaã«ã¯ãããã°ã©ã å¯èœãªarduinsãã¯ãããŸããããããå¶åŸ¡ããã«ã¯ãã©ãããããïŒãŸãã¯arduinoïŒãäžéšã«ã€ã³ã¹ããŒã«ããRS-232çµç±ã§ãããããšéä¿¡ããå¿
èŠããããŸãã æé€æ©ã§éãã åŸãååº«ã®æ£ã®1ã€ã«ã»ãããã€ãããŸãŸã«ããŸããã

ä»å¹Žã
Microsoft Robotics Development StudioïŒMRDSïŒã詊ããŠã¿ãããšã«ããŸããããããä¿é²ããããã«ãMicrosoftã¯ãæšæºããããããå¶åŸ¡ããæ©åšãšãããã³ã«ã®ã»ããã§ãã
ãMRDSãªãã¡ã¬ã³ã¹ãã©ãããã©ãŒã ãã®ä»æ§ãçå®ããŸããã ãã®ä»æ§ã«ãããããããæå¥œå®¶ã¯äºææ§ã®ãããããããäœæããããããéã§ããã°ã©ã ã転éã§ããŸãã æé€æ©ã®ããŒããŠã§ã¢ãšæ¯èŒããŠããªãã¡ã¬ã³ã¹ãã©ãããã©ãŒã ã¯ããè€éã§åŒ·åã§ãã仿§ã«ã¯ãKinectã3ã€ã®èµ€å€ç·è·é¢èšã2ã€ã®è¶
鳿³¢è·é¢èšããã€ãŒã«å転ã»ã³ãµãŒïŒãšã³ã³ãŒããŒïŒãå«ãŸããŸãã ãããŸã§ã®MRDS RPã®å®è£
ã¯ã
Eddie ïŒKinectãå«ãŸãªãçŽ1000ãã³ãïŒãšåŒã°ããParallaxã«ãã£ãŠã®ã¿æäŸãããŠããŸãã EddieãšMRDS RP仿§ã®ãããã¿ã€ãããããã®åçãšã®ç°åžžãªé¡äŒŒæ§ã¯ã仿§ãParallaxãšã®å¯æ¥ãªã³ã©ãã¬ãŒã·ã§ã³ã§äœæãããããšã瀺ããŠããŸããèšãæãããšãParallaxã¯Microsoftã«ãã©ãããã©ãŒã ãåèã«ãããããšã«æåããŸããã
ããŸããŸãªã»ã³ãµãŒã«å ããŠãEddieã«ã¯æ©æ¢°çã«å°è±¡çãªãã©ãããã©ãŒã ïŒ20 kgã®è² è·å®¹éã宣èšãããŠãããããèªäœã®åã«å庫ããŒããŒãæŒãã®ã«ååãªã¢ãŒã¿ãŒé»åããããŸãïŒãšãããã°ã©ããã«ã³ã³ãããŒã©ãŒParallax Propellerãã€ãŸã éèŠãªã³ãŒãã¯ãã³ã³ãã¥ãŒã¿ãŒããçŽæ¥åœä»€ããã ãã§ãªããããããã«çŽæ¥çž«ãä»ããããšãã§ããŸãã

British Channel 4
㯠ãGadget Manããã°ã©ã ã®
ãªãªãŒã¹ã®1ã€ã«ãã·ã§ããã³ã°ã«ãŒãã«çµ±åãããEddieã®ãã¢ãå«ã2åéã®æçãå«ããŸããã æ®å¿µãªãããè±åœã®IPã¢ãã¬ã¹ã®ææè
ã®ã¿ããã£ã³ãã«4ã®Webãµã€ãã§ããã°ã©ã ãèŠãããšãã§ããŸãããç§ã¯ãããã€ããã§ãªããŒãããããšãã§ããŸããã§ããïŒããããèªè
ã®äžéšã¯æåããã§ããããïŒã

ææŠãã
ããããããååŸå·Šå³ãã ãã§å¶åŸ¡ããã®ã¯é£ããããšã§ã¯ãããŸããããã®ãããªããªã¢ãŒãå¶åŸ¡ãã®ããã°ã©ã ã¯ãšãã£ã®é
ä¿¡ã«çŽæ¥å«ãŸããŠããŸãã ããããããããããŒããŒã®ããã¯ãæçžŠãã人ã¯ããŸãããåèªãå庫ã®ã©ã®ãã€ã³ãã«ããããèªèããæ¬¡ã®ãã€ã³ãã«é²ãå¿
èŠããããŸãã ãã®äœçœ®ã®å®çŸ©ã§ãäž»ãªåé¡ãçããŸããã GPSã®ãããªæè¡ã¯äžæãããŠããŸããè¡æããã®ä¿¡å·ã¯å庫ã®å±æ ¹ãééããŸããã Kinectã¯ãžã§ã¹ãã£ãŒèªèã«é©ããŠããŸãããã¹ãã¬ãŒãžã·ã§ã«ããã©ã®ããã«èªèããŸããïŒ æ£èªäœã«ã¯ãã¡ãŒã¿ãŒããšã«äžæã®ããŒã³ãŒãã貌ãä»ããããŠããŸããããŸããå€åºå
ã§æ£ãã20 cmé¢ããå Žæã§ã¯ããŸãä¿¡é Œæ§ã®é«ãããŒã³ãŒããèªã¿åããŸããïŒè¿ã¥ããŸãã-ãµããŒãã«ã¶ã€ãã£ãããæ£ããçªãåºãŠããç®±ã«ã¶ã€ããå±éºããããŸãïŒã 第äºã«ã20cmã®è·é¢ã§æ£ã«ç§»åããŠããŒã³ãŒããèªã¿åãã«ã¯ãçŸåšã®äœçœ®ã
倧ãŸãã«çè§£ããå¿
èŠããããŸãããããªããã°ãæ£ããæšªã«ç§»åããããããã¯å®å
šã«åãè¿ãã®ã€ããªãæ¹åã倱ããŸãã

æåã®ããã²ãŒã·ã§ã³ã®è©Šã¿ã¯ãè·é¢èšã«åºã¥ããŠããŸãããããããã¯æ£ããæš¡çŽ¢ãããããã«æ²¿ã£ãŠç§»åããéæ®µããå£ã«å¯ãããã£ãŠé©ç°çãªé
ã£ã±ãããæ©ãããã«ãæå®ã®è·é¢ãç¶æããŸãã é¡äŒŒæ§ã¯éåžžã«å€§ããã£ãïŒè·é¢èšããã®ä¿¡å·ã®åä¿¡ãMRDSã§ã®ä¿¡å·ã®åŠçãã¢ãŒã¿ãŒã®ããŒã ã®åœ¢æãæ
£æ§ã®å
æã®é
å»¶ã¯10åã®1ç§ã§ããã ãã®éãããããã¯å·éã«æšªã«ãåŒãé¢ããããã®ã§ããã®ãã³ã«ãã³ãŒã¹ä¿®æ£ãã¯æ°å床ã«ãªããè»éã¯åºããžã°ã¶ã°ã«ãªããŸããã ããã«å ããŠããšãã£ã®è·é¢èšã¯éåžžã«æ£ç¢ºã§ã¯ãããŸããã§ãã-ãšã©ãŒã¯æå€§Â±5cmã§ã-ãšéåžžã«çãçŠç¹ãããªãã¡ æ£ã¯ãåºããæå®ã®é«ãã®1ã€ã ãã§èªèãããŸããã
ããææãªã®ã¯ããã€ãŒã«ã»ã³ãµãŒã®ããã²ãŒã·ã§ã³ã§ãåãã€ãŒã«ã®èµ°è¡è·é¢ãçŽÂ±7mmã®ç²ŸåºŠã§äžããŸããã Eddieãã¡ãŒã ãŠã§ã¢ã«ã¯ãããããã®èµ°è¡è·é¢ãïŒäž¡è»èŒªã®èµ°è¡ã®ååïŒãšãããããã®æ¹åãïŒè»èŒªã®èµ°è¡è·é¢ã®å·®ãæ£èŠåä¿æ°ïŒã®èšç®ãæ¢ã«å«ãŸããŠããŸãããçŸåšã®åº§æšïŒxãyïŒã¯2ã€ã®ã«ãŠã³ã¿ãŒã®å€ããèšç®ã§ããŸãã ããããã®è»éãå°ããªåçŽãªã»ã¯ã·ã§ã³ã«åå²ããåã»ã¯ã·ã§ã³ã®åããèŠçŽããå¿
èŠããããŸãã äžèŠãç Žç·ããããã®çµè·¯ãè¿ã¥ããããšæããŸãã ãããå®éã«ã¯ãã鿢ã-ã¢ãŒã¿ãŒã®äžå®é床ã§-ããããã¯åã®åŒ§ã«æ²¿ã£ãŠç§»åããŸããååŸã倧ããã»ã©ãã¢ãŒã¿ãŒã®é床ã®å·®ã¯å°ãããªããŸãã ããã©ãããããã¬ãŒã¯ãã€ã³ãã¯ããããããã¹ãããããç§»åããã«æ¹åã倿Žããå Žåãå®éã«ã¯ååšããååšããããšã¯ã§ããŸããã ãããã£ãŠãããããã®è»éãäžé£ã®å匧ã§è¿äŒŒããŸãã
èšç®
ããã¯ãã¹ãŠãå€é
ãã«ãããã³ã«çµµãæãããšããå§ãŸããŸããã

ã¢ãŒã¯ã®éå§æãããããã¯ç¹
A ïŒæ¢ç¥ïŒã«ãããæåŸã«ç¹
B ïŒæªç¥ïŒã«ãªããå·Šè»èŒªã¯æ¢ç¥ã®çµè·¯
S 1 =
Ïr1ããå³è»èŒªã¯æ¢ç¥ã®çµè·¯
S 2 =
Ïr2ãç§»åããŸãã ã ãã©ãã¯éã®è·é¢
wã¯äžå®ã§ãããããããã®èšèšã«ãã£ãŠæ±ºãŸããŸãã ååŸãããã®ïŒ
r 2 /
r 1 =
S 2 /
S 1ããã³
r 2 =
r 1 +
wïŒ
r 1 +
w ïŒ/
r 1 =
S 2 /
S 1r 1 S 1 +
wS 1 =
r 1 S 2r 1 =
wS 1 /ïŒ
S 2 -
S 1 ïŒ
ãããã£ãŠããããããå転ããè§åºŠã¯
Ï =
S 1 /
r 1 =ïŒ
S 2 -
S 1 ïŒ/
wã§ãããè·é¢|
AB | = 2 |
AM | = 2ïŒ
r 1 +
w / 2ïŒsinïŒ
Ï / 2ïŒ=ïŒ2
wS 1 /ïŒ
S 2 -
S 1 ïŒ+
w ïŒsinïŒ
Ï / 2ïŒ=
w sinïŒ
Ï / 2ïŒïŒ
S 2 +
S 1 ïŒ/ïŒ
S 2 -
S 1 ïŒ
ããã§ãæŠããŠãäœçœ®ã決å®ããããã®ãã¹ãŠã®æ°åŠïŒèšç®ããã
Ïãããããã®æ¹åã®è§åºŠã«è¿œå ããçŸåšã®åº§æšãè·é¢ã ãã·ãããããã³ã«|
AB |ã å®çšçãªåé¡ã¯æ®ã£ãŠããŸãïŒãã®ãããªäœçœ®ã®æŽæ°ãå®è¡ããé »åºŠã¯ïŒ äœãã«ãé »ç¹ã«ãç§éã¯é¢æ£çãªãå»ã¿ç®ãã§èµ°è¡è·é¢ã枬å®ããè»èŒªã»ã³ãµãŒã®äžæ£ç¢ºãã«åºããããŸãã ããŸãã«ãŸããªå Žåãåã®åŒ§ã«ããçµè·¯ã»ã°ã¡ã³ãã®è¿äŒŒã¯ååã«æ£ç¢ºã§ã¯ãããŸããã
ãã€ãŒã«ã»ã³ãµãŒã®èªã¿åãå€ã¯ããã£ãã¯ãã®æç¹ã§æãæ£ç¢ºã§ãããšå€æããããããã€ãŒã«ã®ãã£ãã¯ããšã«ããããã®äœçœ®ãåèšç®ããŸãããã ããçŽ80ããªç§ååŸã«èšé²ãããããããã®èª¿æ»æéãè¶
ããŸããã å°ãªããšã1ç§éã«1åã忢ãããã€ãŒã«ïŒããšãã°ãå転äžïŒãèšé²ãããããã«ããŸãã ç»é²ããããã¹ãŠã®ããã£ãã¯ãã¯ãªã¹ãã«ä¿åãããŸããããã¯ãäœçœ®ãåèšç®ããããã«ãäž¡æ¹ã®ãã€ãŒã«ãåãæéå®è¡ããå¿
èŠãããããã§ãã äž¡æ¹ã®ãã€ãŒã«ã§ä»¥åã®ããã£ãã¯ã
ã®æ©ãæ¹ããééãåããããã£ãã¯ã®ãªã¹ããã«åŸã£ãŠåãç¬éã«2çªç®ã®ãã€ãŒã«ã®èµ°è¡è·é¢ãç·åœ¢è£éããŸãã ã®ã£ããã®çµããã«ã€ããŠã¯ãåæ§ã«ãç®çãä»ããã€ãŒã«ã®ã»ã³ãµãŒãèªã¿åã£ãèµ°è¡è·é¢ãååŸãã2çªç®ã®èµ°è¡è·é¢ãçŽç·çã«å€æ¿ããŸãã ãããã£ãŠã粟床ã¯å¯èœãªéãéæå¯èœã§ãªããã°ãªããŸããã
ããããã®äœçœ®ãåèšç®ããããã³ã«ããããããæå®ãããã¿ãŒã²ããã«åããããã«ãè»èŒªã®éåºŠãæ°ããæ¹æ³ã§èšå®ããå¿
èŠããããŸãã ãããããæå®ã®ãæ¹äœè§ãã«æ£ç¢ºã«åããŠå®äœçœ®ã§å転ãããã®ã¯éçŸå®çã§ããåè¿°ã®Â±7 mmã®ãã€ãŒã«ãã€ã¬ãŒãžãšã©ãŒã¯ããããããå転ãããšæ°åºŠã®ãšã©ãŒã«ãªããŸãã ããããã¯æ
æã«ãã©ã³ãã ã«ãç§»åããéè·¯ã«æ²¿ã£ãŠåã³æåããå¿
èŠããããŸãã ãããã£ãŠãã¿ãŒã²ãããžã®æ¹åãçŸåšã®æ¹åãšããŸãéããªãå Žåã¯ãäºåã«ãæ¹äœè§ã«åãããããšãªããã¢ãŒã¯ã«æ²¿ã£ãŠãããããã¿ãŒã²ããã«åããããšã«ããŸããã ïŒçŸåšã®æ¹åãåžæã®æ¹åãš
Ï / 2ç°ãªãå Žåããã®ãããªå匧ã¯ååãã倧ãããªããŸããããã¯æããã«éçŸå®çã§ãããã®å Žåãããããã¯æ£ããæ¹åã«å転ãã以å€ã«éžæè¢ããããŸãããïŒ
ã¢ãŒã¯ãèšç®ããã«ã¯ãäžã®å³ã«æ»ããŸãããã ããã§ããã€ã³ã
Aãš
Bãããã£ããããè§åºŠ
ÏãããããŸããã æ¯ç
S 2 /
S 1 =
r 2 /
r 1ãèŠã€ããå¿
èŠããããŸããããã¯ãã¢ãŒã¯ã«å¿
èŠãªè»èŒªéåºŠã®æ¯çãèšå®ããŸãã äžèšã®èšç®ãå察æ¹åã«ç¹°ãè¿ããŸãã
|
AB | = 2 |
AM | = 2ïŒ
r 1 +
w / 2ïŒsinïŒ
Ï / 2ïŒ
r 1 = |
AB | /ïŒ2sinïŒ
Ï / 2ïŒïŒ-
w / 2
r 2 = |
AB | /ïŒ2sinïŒ
Ï / 2ïŒïŒ+
w / 2
r 2 /
r 1 = 1 +
w /ïŒ|
AB | /ïŒ2sinïŒ
Ï / 2ïŒïŒ-
w / 2ïŒ= 1 + 2 /ïŒ|
AB | /ïŒ
wã»sinïŒ
Ï / 2ïŒïŒ-1 ïŒ
ãã®ãããªã¢ãŒã¯ã¯ãã©ã€ã³
ABããã©ã®çšåºŠé¢ããŸããïŒ ãããããå匧ã宿ãããããã«äž¡åŽã«2ã¡ãŒãã«ã®ç©ºãã¹ããŒã¹ãå¿
èŠãšããå Žåãå庫ã«ã¯ãã®ãããªæ©äŒã¯ãããŸãããæ£éã®éè·¯ã®å¹
ã¯1.5ã¡ãŒãã«ãããããŸããã

è·é¢ãèšç®ãã|
Mh | å匧ãšç·ã®éïŒ|
OH |-|
OM | =
r -
r cosïŒ
Ï / 2ïŒ=ïŒ
r 1 +
w / 2ïŒïŒ1-cosïŒ
Ï / 2ïŒïŒ
ãã®ããã³ããã®å€§ãããæå®ã®å¶éãè¶
ããå Žåã匧ãæãããã«ç§»åããããšãæåŠããæå®ã®äœçœ®ã§å転ããŠãã¿ãŒã²ããã«åãã£ãŠè¿ã¥ãããšããŸãã
倿ããããã«ãå®éã«ã¯ãã¢ãŒã¿ãŒã®ã¹ãã¬ã¹ã®æ¯çã¯ãŸã è»èŒªéåºŠã®æ¯çãæ±ºå®ããŠããŸããã ãããã®éã§æ£ãã倿ãéžæããããšã¯å¯èœã§ãããç§ã¯ããã«ãŒããã©ãŒã¹ãã§åé¡ã解決ããŸããïŒç§ã¯æ¯çã9床ã«äžããŸããã çåŽãžã®ããããªåå·®ã¯ãããã«ãããããå察æ¹åã«åŒ·ãæŒããŸãã å®éãããããã®åããæ¬åœã«æ»ããã«ãªã£ãã®ã¯ãã®ææ°ã§ãããè§åºŠãå°ãããªããšãããããã¯æšªã«å€§ããå€ããã¿ãŒã²ããèªäœã§ã®ã¿æ£ããã«ãŒãã«æ»ããŸããã 倧ããªãã®ã§ã¯ãè£æ£ã匷ãããããšã倿ããããããã¯çããžã°ã¶ã°ã§å·Šå³ã«ãæºãããŸããã
å®è£
ReferencePlatform2011é
ä¿¡ããMarkRobotãµãŒãã¹ã«æ°ããæ©èœã远å ããããšãèšç»ããŠããŸãããPositionOperationsã®ç²Ÿç¥ã§æ°ããããŒãã¬ãããå®è£
ããŸã
PositionOperations : PortSet<GetPosition, SetPosition, SetDestination>
ã å®éããã®å®è£
ã«ã¯è³ããŸããã§ããããµãŒãã¹éã§è²¬ä»»ãåé¢ããã«æºåã§ããã®ã¯æ³¥ã ããã®ãããã¿ã€ãã ãã§ããã ããããç§ããã£ãããšãèŠããããšããŸãã
æåã«ã座æšãæäœããããã«äœããå¿
èŠã§ããããããä¿åããããã«
System.Drawing.PointF
ã¯ãããŸããã
public struct Position { public readonly double x, y, heading; public Position(double x, double y, double heading) { this.x = x; this.y = y; this.heading = heading; } private static double Sqr(double d) { return d * d; } public double DistanceTo(double x, double y) { return Math.Sqrt(Sqr(this.y - y) + Sqr(this.x - x)); } public static double NormalizeHeading(double heading) { while (heading < -Math.PI) heading += 2 * Math.PI; while (heading > Math.PI) heading -= 2 * Math.PI; return heading; }
advance
ã¡ãœããã¯ãæå®ãããå転è§
Ïãšç§»åè·é¢|ã®åº§æšã®åèšç®ãå®è£
ããŸãã
AB |ïŒèšäºã®äžå€®ã®å³ã®ããã«ïŒã
ïŒä»ãããã«ã³ãŒããã³ããŒããŠãç§ã¯æ£ç¢ºã«ãäºéè§åºŠåŒããååŸããè§åºŠ
Ï / 2ã§|
AB |ã ãã·ãããã代ããã«ãè§åºŠ
Ïã§ r 1 +
w / 2ã ãç§»åã§ããããšã«æ°ä»ããŸããããŸããïŒ
ããã«ããµãŒãã¹ã«ã¯
PositionKeeping
ã€ã³ã¹ã¿ã³ã¹ãå«ãŸããŠããããã®å
éšã«ã¯
EncoderLog
2ã€ã®ã€ã³ã¹ã¿ã³ã¹ããããŸããã
EncoderLog
ãªã¹ãããåãã€ãŒã«ã®åå¥ã®ã€ã³ã¹ã¿ã³ã¹ã§ãã ïŒçè«çã«ã¯ïŒã»ã³ãµãŒããŒã¿ã¯æç³»åã§å°çããªãå¯èœæ§ãããããããªã¹ãã¯
SortedList
ã«
SortedList
ããŸãã
EncoderLog
å¯äžã®éèŠãªæ¹æ³ã¯ãããã£ãã¯ãã®éãŸãã¯æåŸã®ããã£ãã¯ãã®åŸã®ä»»æã®æç¹ã§å€ãååŸããããã®ãã¹ã®ç·åœ¢è¿äŒŒã§ãã
private class PositionKeeping { private static readonly DateTime initialized = DateTime.Now; public class EncoderLog { private SortedList<DateTime, double> log = new SortedList<DateTime, double> { { initialized, 0 } }; public void Register(DateTime at, double reading) { log[at] = reading; } public void Reset(DateTime at, double reading) { log.Clear(); log.Add(at, reading); } public DateTime LastTick { get { return log.Last().Key; } } public double LastReading { get { return log.Last().Value; }} public double ReadingAt(DateTime at) { int index = log.Count - 1; while(index>=0 && log.Keys[index] > at) index--; if(index<0) return double.NaN;
ããã£ãã¯ãªã¹ããã«å ããŠãåããã£ãã¯ãæ
ã®äœçœ®ã®ãªã¹ãã PositionKeeping
ã«ä¿åããå¿
èŠããããŸãããã®ä¿åãããäœçœ®ãããç§»åããè·é¢ã枬å®ããŠæ°ããäœçœ®ãååŸããŸãã
private SortedList<DateTime, Position> position = new SortedList<DateTime, Position> { { initialized, new Position(0, 0, Math.PI / 2) } }; public void Register(DateTime at, Position pos) { position.Add(at, pos); } public void Reset(DateTime at, Position pos) { // the position has changed => old ticks logs become obsolete leftEnc.Reset(at, leftEnc.ReadingAt(at)); rightEnc.Reset(at, rightEnc.ReadingAt(at)); position.Clear(); position.Add(at, pos); } public Position Current { get { return position.Last().Value; } }
å°åºãããå
¬åŒã«åŸã£ãŠãäž¡æ¹ã®ãã€ãŒã«ã»ã³ãµãŒã®ããŒã¿ã«åŸã£ãŠæ°ããäœçœ®ãèšç®ããããšã«ããã
PositionKeeping
ã¯ã©ã¹ãè£å®ããŸãã
Update
ã¯ã»ã³ãµãŒãã§ãã¯ãµã€ã¯ã«ïŒ
ServiceHandlerBehavior.Concurrent
ïŒããåŒã³åºãããšãã§ãããµãŒãã¹ããŒããåŒæ°ãšããŠåãåãããã£ãã¯ãç»é²ããããšæ°ãã座æšãéä¿¡ããŸãã ãã®ã¡ãã»ãŒãžã¯ãµãŒãã¹ã®ç¶æ
ã倿Žããããã
ServiceHandlerBehavior.Exclusive
ãšããŠæ±ãå¿
èŠããããŸãã
private static readonly TimeSpan RegisterDelay = TimeSpan.FromSeconds(1); // register null-tick if no actual ticks for this long public void Update(DateTime at, double left, double right, PositionOperations mainPort) { DateTime prevRef = Min(leftEnc.LastTick, rightEnc.LastTick); SetPosition set = new SetPosition { Timestamp = at, LeftEncUpdated = left != leftEnc.LastReading || at > leftEnc.LastTick + RegisterDelay, LeftEncReading = left, RightEncUpdated = right != rightEnc.LastReading || at > rightEnc.LastTick + RegisterDelay, RightEncReading = right }; if(set.LeftEncUpdated || set.RightEncUpdated) { set.Position = Recalculate(prevRef, left, right); mainPort.Post(set); } } private Position Recalculate(DateTime prevRef, double left, double right) { double sLeft = left - leftEnc.ReadingAt(prevRef), sRight = right - rightEnc.ReadingAt(prevRef); Position refPos = position[prevRef]; // has to exist if the encoder reference exists if (Math.Abs(sRight - sLeft) < .5) // less then half-tick difference: go straight return refPos.advance(Constants.CmPerTick * (sRight + sLeft) / 2, 0); else { double angle = Constants.CmPerTick * (sRight - sLeft) / Constants.WheelsDist, distance = Constants.WheelsDist * Math.Sin(angle / 2) * (sRight + sLeft) / (sRight - sLeft); return refPos.advance(distance, angle); } } }
ç®çã®ã³ãŒãã«æ®ã£ãŠããã®ã¯
SetPosition
ãã³ãã©ãŒã ãã§ããããã¯ããããããã¿ãŒã²ããã«åãã£ãŠç§»åããããã«ã¢ãŒã¿ãŒã®é»å§ãèšå®ããŸãã
[ServiceHandler(ServiceHandlerBehavior.Exclusive)] public void SetPositionHandler(SetPosition set) { if (!set.LeftEncUpdated && !set.RightEncUpdated) { // position updated by an absolute reference. positionKeeping.Reset(set.Timestamp, set.Position); } else { if (set.LeftEncUpdated) positionKeeping.leftEnc.Register(set.Timestamp, set.LeftEncReading); if (set.RightEncUpdated) positionKeeping.rightEnc.Register(set.Timestamp, set.RightEncReading); positionKeeping.Register(set.Timestamp, set.Position); } // the navigator Destination dest = state.dest; double distance = set.Position.DistanceTo(dest.x, dest.y); if (distance < 5) // reached { drivePort.SetDrivePower(0, 0); SendNotification(submgrPort, new DriveDistance()); return; } double heading = Position.NormalizeHeading(Math.Atan2(dest.y - set.Position.y, dest.x - set.Position.x)), power = (distance < 50) ? .2 : .4; // a few magic numbers if (Math.Abs(heading) < .05) { // straight ahead drivePort.SetDrivePower(power, power); return; } double r = distance / (2 * Math.Sin(heading / 2)), hump = r * (1 - Math.Cos(heading / 2)); if (Math.Abs(heading) > Math.PI / 2 || Math.Abs(hump) > Constants.MaxHump) { // not reachable by an arc; rotate if (heading > 0) // rotate left drivePort.SetDrivePower(-.3, .3); else // rotate right drivePort.SetDrivePower(.3, -.3); } else { // go in arc double rLeft = Math.Abs(r - Constants.WheelsDist / 2), rRight = Math.Abs(r + Constants.WheelsDist / 2), rMax = Math.Max(rLeft, rRight); // <Patrician|Away> what does your robot do, sam // <bovril> it collects data about the surrounding environment, then discards it and drives into walls drivePort.SetDrivePower(power * Math.Pow(rLeft / rMax, 9), power * Math.Pow(rRight / rMax, 9)); } }
次ã¯ïŒ
ãã®ããããã¯ããªãããŸãé転ããŸãããã环ç©ãšã©ãŒã®ããã«åé¡ãçºçããŸããã 座æšãä¿®æ£ããã«ã¯ãããŒã³ãŒãã®å°ãªããšã20ïŒ
ãæ£åžžã«èªã¿åãã
LeftEncUpdated = RightEncUpdated = false
ã§
LeftEncUpdated = RightEncUpdated = false
åŒã³åºããŠ
PositionKeeping
ããåèµ·åã
PositionKeeping
SetPosition
ã§
LeftEncUpdated = RightEncUpdated = false
ã§ãã ããŒã³ãŒãã®èªã¿åãééãæ°ã¡ãŒãã«ã®å Žåã座æšã決å®ããéã®ãšã©ãŒã¯20 cmãè¶
ããŸããã§ãã-ãããããšæ£ã®éã«ããŸãã«ãå€ãæ®ããŸããã
æ¹åãä¿®æ£ãããã®ãäœããªããããããã£ã³ã°ãšã©ãŒã®ç¶æ³ã¯ããã«æªåããŸãããããŒã³ãŒãã¯ã©ã®è§åºŠããã§ãèªã¿åãããšãã§ããŸãïŒãããŠç¥ã«æè¬ããŸãïŒã æ°åºŠã®çޝç©èª€å·®ã¯ããããããã©ã³ãã ã«ä¹ã£ãŠå
šåã§é£éã«å
¥ãã«ã¯ãã§ã«ååã§ãã æ£é¢ã®è§£æ±ºçã¯ããžã£ã€ãã¹ã³ãŒããèšçœ®ããããšã§ãã ããããEddieçšã®æ¢è£œã®ãžã£ã€ãã¯ãããŸãããã¯ãã ããŠãšãã¡ãŒã ãŠã§ã¢ã®æžã蟌ã¿ã§è¬ãåé¿ããããšæããŸãã
ãžã£ã€ãã¹ã³ãŒããä»ã®ãšããŸããã¯ãªã»ã³ãµãŒãªãã§æ¹åãä¿®æ£ããã«ã¯ã次ã®èšäºã«å°å¿µããŸãã