Final1 5

  • Uploaded by: Vlad
  • 0
  • 0
  • August 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Final1 5 as PDF for free.

More details

  • Words: 5,899
  • Pages: 37
Final Report

‫‪.1‬פרק ‪ - 1‬מבוא‬ ‫‪.1.1‬ניסויים התנהגותיים‬ ‫ניסויים נוירופיזיולוגיים התנהגותיים דורשים רישום אותות חשמליים מבעל‬ ‫חיים חי ובמקרים מסוימים גם מתנהג‪ ,‬כשהתנהגות מוגדרת כתגובה של בעל‬ ‫החיים לגירויים חיצוניים‪.‬‬ ‫קיים מספר רב של פרוטוקולים לניסויים התנהגותיים‪ .‬ניתן לחלק אותם‬ ‫לקבוצות לפי סוגי גירוי ודרגות התנהגות ובהתאם לכך גם דרישות ממערכת‬ ‫הניסויית ומתוכנה התנהגותית‪.‬‬ ‫‪.1‬קבוצה של ניסויים בהם הנבדק רדום‪ .‬הגירוי החשמלי מוכל על‬ ‫נוירון מסוים או קבוצת נוירונים והתגובה ה"התנהגותית" נמדדת‬ ‫באזור אחר מתא בודד או קבוצה של תאים‪.‬‬ ‫בניסויים מסוג זה אין צורך במערכת התנהגותית‪ ,‬כל הדרוש הן‬ ‫אלקטרודות לגירוי ואלקטרודות לרישום (בד"כ ‪.)Patch-clamp‬‬ ‫‪1. Henrik Jo¨rntell, Carl-Fredrik Ekerot (2006) Properties of Somatosensory‬‬ ‫‪Synaptic Integration in Cerebellar Granule Cells In Vivo. J Physiol‬‬

‫‪.2‬קבוצה של ניסויים בהם הנבדק ער ונדרש לבצע פעולה‬ ‫התנהגותית פשוטה יחסית‪ ,‬כגון להסתכל על נקודה מסוימת‬ ‫במרחב או לחיצה על כפתור‪ .‬בניסויים מסוג זה בנוסף למערכת‬ ‫הרישום ישנה גם מערכת התנהגותית‪ ,‬כגון תוכנה התנהגותית‬ ‫אשר מציגה את התמונות לנבדק או בודקת האם הכפתור נלחץ‬ ‫וכדומה‪.‬‬ ‫‪1. AK Kreiter, W Singer (1996) Stimulus-dependent synchronization of‬‬ ‫‪neuronal responses in the visual cortex of the awake macaque monkey.‬‬ ‫‪Journal of Neuroscience‬‬ ‫)‪2. Thomas Wachtler, Terrence J. Sejnowski, Thomas D. Albright (2003‬‬ ‫‪Representation of Color Stimuli in Awake Macaque Primary Visual‬‬ ‫‪Cortex, Neuron‬‬

‫‪.3‬קבוצה של ניסויים בהם הנבדק ער ונדרש לבצע פעולות מוטוריות‬ ‫מסובכת יחסית‪ .‬בעל החיים מתנהג במלא מובן המילה‪ .‬בנוסף‬ ‫למערת הרישום נדרשת חומרה אשר מייצרת גירויים (ויזואליים‪,‬‬ ‫קוליים‪ ,‬הָפטיים וכדומה) ומודדת את התנועה (כוון‪ ,‬מהירות‪,‬‬ ‫כוח)‪.‬‬ ‫‪1. Kris M. Horn, Milton Pong and Alan R. Gibson (2003) Discharge of‬‬ ‫‪inferior olive cells during reaching errors and perturbations, Brain‬‬ ‫‪Research‬‬

‫‪.4‬קבוצה של ניסויים בהם הנבדק מקבל גירויים משולבים ממערכת‬ ‫‪ .)VR (Virtual Reality‬מערכות כאלה בד"כ כוללות רובוטים‬ ‫הָפטיים ומחשב בעל יכולת הצגה של תמונה תלת‪-‬ממדית‪.‬‬ ‫מטרת המחקר של ד"ר עופר דונחין היא לחקור את תפקידם של קורטקס המוטורי‬ ‫והצרבלום בלמידה מוטורית‪ ,‬ולכן הנבדקים יהיו ערים ויבצעו משימות התנהגותיות‬

‫שונות‪ .‬למידה מוטורית תושג ע"י הפעלת כוחות הפרעה (‪ )Perturbation forces‬על‬ ‫הגפה שתבצע את המשימה וחזרה על המשימה עד שהתבנית של התנועה עם‬ ‫ההפרעה תהיה דומה לתבנית של התנועה בלי ההפרעה‪ .‬הניסויים לא יכללו (לפחות‬ ‫לא בשלב הראשון) הדמיה וירטואלית (‪.)VR‬‬ ‫‪.1.2‬מבנה כללי של המערכת‬ ‫מערכת הניסוי מורכבת ממרכיבי חומרה שונים ותוכנה התנהגותית‪.‬‬

‫‪Perturbation Phantom‬‬ ‫‪Reward Phantom‬‬ ‫‪Food Pump‬‬ ‫‪Sound cue‬‬ ‫‪Force Plates‬‬ ‫‪Behavioral Software‬‬

‫‪1.‬‬ ‫‪2.‬‬ ‫‪3.‬‬ ‫‪4.‬‬ ‫‪5.‬‬ ‫‪6.‬‬

‫מערכת הניסוי כוללת את כל המרכיבים הדרושים לביצוע ניסוי התנהגותי‬ ‫ולבצע את כל המשימות הדרושות‪.‬‬ ‫המערכת כוללת שני רובוטים הָפטיים – פאנטומים‪ ,‬כאשר לכל אחד מהם‬ ‫תפקיד שונה‪ .‬תפקידו של פאנטום (‪ )1‬פרמיום (‪ )Premium‬הוא להפעיל כוחות‬ ‫מפריעים (‪ )Perturbation forces‬על הגפה של החתול‪ .‬הכוחות יכולים להיות‬ ‫מסוגים שונים ודרגות שונות של מורכבות‪ :‬כוח קבוע בכוון קבוע‪ ,‬כוח קבוע‬ ‫המאונך לכוון התנועה‪ ,‬כוח משתנה בהתאם למהירות וכוון התנועה וכו'‪.‬‬ ‫תפקידו של פאנטום (‪ )2‬אומני (‪ )Omni‬הוא לשמש מטרה (גירוי ויזואלי) שאותה‬ ‫החתול ירצה לתפוס כדי לקבל תגמול‪ .‬פאנטום זה מספק את המסגרת של מהלך‬ ‫הניסוי ומבחינת החתול זהו הממשק הוויזואלי של המערכת‪ .‬הוא לא מפעיל‬ ‫כוחות על החתול‪ ,‬אלא מבצע פעולות כגון‪ :‬הגעה לנקודה שבה הוא נגיש לחתול‪,‬‬ ‫המתנה בגובה מסוים‪ ,‬הדמיה של משטח חסר חיכוך וכולי‪ ,‬בהתאם לדרישות‬ ‫מהלך הניסוי‪.‬‬

‫תפקידה של המשאבה הוא לספק את האוכל (התגמול) לחתול‪ .‬האוכל יכול‬ ‫להינתן בצורה אוטומטית לפי ההגדרות של הניסוי או בצורה ידנית ע"י לחוצה‬ ‫על כפתור בתוכנה‪.‬‬ ‫החתול יקבל סימנים קוליים בשלבים שונים של הניסוי‪ ,‬למשל‪ ,‬צליל שיסמן את‬ ‫תחילת הניסוי‪.‬‬ ‫תפקידם של ‪ force plates‬הוא לספק מידע נוסף למערכת על מיקומו והתנהגותו‬ ‫של החתול בזמן הניסוי‪ .‬לפי המשקל ניתן לדעת האם החתול עומד עם שני‬ ‫הגפיים‪ ,‬מושיט גפה וכו'‪.‬‬ ‫כל המערכת מנוהלת ע"י תוכנה התנהגותית‪ .‬היא זו שיודעת לאסוף את כל‬ ‫המידע מכל החומרה ולנהל את הניסוי לפי תוצאות העיבוד של מידע זה‪.‬‬ ‫‪.1.3‬תאור התוכנה ההתנהגותית‬ ‫תוכנת ‪ Cats‬היא תוכנה התנהגותית אשר מנהלת את כל ההיבטים של הניסוי ע"י‬ ‫כך שמספקת לחוקר כלים פשוטים‪ ,‬אך גמישים‪ ,‬להרכבת מהלך הניסוי‪ ,‬שליטה‬ ‫על ביצועו‪ ,‬ע"י שליטה על כל מרכיבי החומרה והסנכרון ביניהם‪ ,‬ושליטה על‬ ‫התנהגות בעל החיים (באמצאות החומרה) כאשר מבצע תנועות ההושטה במהלך‬ ‫הניסוי‪.‬‬

‫‪.1‬פרק ‪ – 2‬רקע תכני‬ ‫‪ – Object Oriented Programming .1.4‬תכנות מונחה עצמים‬ ‫תכנות מונחה עצמים הוא פרדיגמה תכנותית שמשתמשת ב"אובייקטים" (‬ ‫‪ )Objects‬ליצירת תוכנות מחשב ואפליקציות‪ .‬שפת ‪ ,++C‬בניגוד לשפת ‪ , C‬היא‬ ‫שפה מונחת עצמים‪.‬‬ ‫מושגים שמתקשרים עם תכנות מונחה עצמים הם הורשה (‪,)Inheritance‬‬ ‫מודולאריות (‪ ,)Modularity‬פולימורפיזם – ריבוי צורות (‪ )Polymorphism‬ו‬ ‫אנקפסולציה (‪.)Encapsulation‬‬ ‫אובייקט בתכנות הוא כמו אובייקט בחיים – יש לו תכונות ויש פעולות שאפשר‬ ‫לעשות איתו (עליו)‪ .‬רכב הוא אובייקט‪ .‬צבע הרכב‪ ,‬מספר גלגלים‪ ,‬יצרן וכו' הן‬ ‫התכונות של הרכב‪ .‬הרכב יכול לנסוע‪ ,‬לעצור‪ ,‬לחנות וכו' – אלא הן הפעולות‬ ‫שהוא יכול לבצע‪.‬‬ ‫הדוגמא הכי פשוטה לאובייקט בתכנות היא משתנה‪ ,‬שהוא סוג של אובייקט‪.‬‬ ‫משתנה מסוג ‪ Integer‬הוא משתנה פשוט‪ .‬המאפיין היחיד שלו (או בשפה יותר‬ ‫מקצועית ‪ )Data member‬הוא הערך שהוא יכול להחזיק‪ .‬הפעולות שאפשר לבצע‬ ‫עליו הן – חיבור‪ ,‬חיסור וכו'‪ .‬כאשר המשתנה מוגדר‬ ‫;‪int iVariable‬‬

‫אנחנו בעצם יוצרים אובייקט מסוג ‪ ,int‬ההגדרה של סוג האובייקט נקראת‬ ‫מחלקה (‪ .)class‬המחלקה היא זו שמגדירה מה הם ה‪ data members-‬של‬ ‫האובייקט ומה הם ה‪ Member functions-‬שלו (הפעולות שאפשר לבצע בהקשר‬ ‫לאובייקט)‪.‬‬ ‫הורשה (‪ )Inheritance‬היא יכולת להשתמש במחלקה קיימת כדי ליצור סוג‬ ‫אובייקט חדש (כמו ההורשה בהקשר הגנטי)‪ .‬למחלקת הבת יהיו אותן תכונות‬ ‫ויכולות כמו למחלקת האם עם אפשרות להוסיף אפשרויות חדשות או לשנות‬ ‫את הישנות‪.‬‬ ‫לדוגמא אם יש לנו מחלקה "בעל חיים" (שתכלול הגדרות הכי כלליות עבור יצור‬ ‫חי) ונרצה להוריש ממנה מחלקה "בן‪-‬אדם" אז נרצה להוסיף למחלקה החדשה‬ ‫תכונה של "דיבור"‪ ,‬וכך "בן‪-‬אדם" מקבל את כל התכונות של "בעל חיים"‬ ‫ובנוסף יודע "לדבר"‪( .‬לא השתמשתי בדוגמא ב"חושב" מכוון שיכולת זו שנויה‬ ‫במחלוקת)‪.‬‬ ‫מודולאריות (‪ )Modularity‬מתארת את היכולת של השפה לקבץ פעולות ליחידות‬ ‫עצמאיות ולהשתמש ביחידות אלה‪ .‬חשיבה מודולארית מאפשרת "למחזר" את‬ ‫הקוד – להשתמש במודול מסוים מספר פעמיים במקום לשכתב את הקוד‪.‬‬ ‫קבוצה של מתכנתים יכולה לחלק את העבודה וכך כל אחד יעובד על המודולים‬ ‫שלו ובסוף רק יחברו אותם ביחד (הגישה הזו מקלה מאוד בעבודה על פרויקטים‬ ‫משוטפים)‪.‬‬ ‫פולימורפיזם (‪ - )Polymorphism‬במילים פשוטות זוהי היכולת להתייחס‬ ‫למחלקת בת כאילו היא מחלקת אם‪ .‬אשתמש שוב בדוגמא של מחלקת "בעל‬ ‫חיים" ומחלקה מורשת ממנה "בן‪-‬אדם"‪ .‬השפה מאפשרת להגדיר מצביע מסוג‬ ‫"בעל חיים" ולהצביע איתו על "בן‪-‬אדם"‪( .‬תכונה זו מאוד הגיונית‪ ,‬כי הרי בן‪-‬‬ ‫אדם הוא רק מקרה פרטי של בעל החיים)‪.‬‬ ‫אנקפסולציה (‪ – )Encapsulation‬המשמעות של המושג היא "הסתרת מידע"‪.‬‬ ‫השאיפה היא שהמשתמש של המחלקה שהוגדרה על‪-‬ידי (משתמש הוא מתכנת‬

‫אחר שרוצה ליצור אובייקט מסוג המחלקה או רוצה להוריש מחלקה‬ ‫מהמחלקה שלי) לא יצטרך לדעת שום דבר על מבנה הפנימי של המחלקה שלי‪,‬‬ ‫הוא ידע רק איך להשתמש בה‪ .‬דוגמא מהחיים – טלוויזיה – רובינו יודעים‬ ‫להשתמש בה‪ ,‬אבל לא יודעים איך היא בנויה‪.‬‬ ‫תכנות מונחה עצמים מאפשר צורת תיכונות שונה מהגישה הקלאסית של שפת‬ ‫‪ ,C‬ונותן למתכנת כלים רבים ומגוונים ליצירת אפליקציות טובות יותר‪ ,‬אך‬ ‫לגישה זו ישנם גם חסרונות מכוון שלא כל רעיון בתכנות ניתן להפוך לאובייקט‬ ‫וגם שימוש מוגזם בחלוקה של משימות לחלקים קטנים יותר ויותר הופך את‬ ‫הקוד ללא ברור ולא קריא‪.‬‬ ‫‪MFC - Microsoft Foundation Class Library.1.5‬‬ ‫זוהי ספריית קוד (‪ )code library‬שעוטפת חלק מ‪ Windows API-‬בתוך מחלקות של‬ ‫‪ ,++C‬במטרה ליצור מסגרת לפיתוח אפליקציות‪ .‬היא כוללת מחלקות רבות‬ ‫המוגדרות כדי לטפל בפקודות מערכת‪ ,‬חלונות ואובייקטים גרפים (‪common‬‬ ‫‪ )controls‬שונים‪ .‬בנוסף‪ ,‬מיקרוסופט הרחיבה את הסינטקס של ‪ ++C‬עם סדרה‬ ‫של מאקרו (‪ )macros‬לניהול של ‪ Windows messages, Exceptions‬וכו'‪.‬‬ ‫‪ MFC‬מספקת מסגרת של ‪ Document/View‬במטרה להפריד את המידע (‪)Data‬‬ ‫מממשק משתמש (‪ ,)User interface‬וכך כאשר עובדים עם המידע שבתוכנה‬ ‫ניגשים ל‪ Document-‬וכאשר עובדים עם ממשק משתמש נגשים ל‪( View-‬אשף‬ ‫הפרויקטים של ‪ Ms Visual Studio‬יוצר שתי מחלקות לפי התבנית ‪AppNameView‬‬ ‫ו‪AppNameDoc -‬ולכן אם התוכנה נקראת ‪ Cats‬מתקבלות שתי מחלקות‪:‬‬ ‫‪ CatsView‬ו‪.)CatsDoc-‬‬ ‫‪.1.6‬ריבוי משימות‪Multithreading ,‬‬ ‫ישנם שני סוגים של ריבוי משימות‪ :‬מבוססות ‪ process‬ומבוססות ‪.thread‬‬ ‫‪ process‬הוא בעצם תוכנה שרצה במחשב וריבוי משימות מבוסס ‪ process‬מאפשר‬ ‫למספר תוכנות לרוץ במקביל‪ .‬בסוג זה של ריבוי משימות ה"תוכנה" היא‬ ‫היחידה הכי קטנה ובסיסית שהמערכת יכולה להריץ‪.‬‬ ‫‪ thread‬הוא יחידה של קוד שניתן להרצה‪ .‬בריבוי משימות מבוסס ‪ thread‬לכל‬ ‫‪ process‬ישנו לפחות ‪ thread‬אחד‪ .‬המשמעות היא שכל תוכנה יכולה לבצע מספר‬ ‫משימות בו‪-‬זמנית‪.‬‬ ‫ניתן לסכם את ההבדלים בין שני הסוגים של ריבוי משימות בכך שריבוי‬ ‫משימות מבוסס ‪ process‬אחראי על הרצה בו זמנית של תוכנות וריבוי משימות‬ ‫מבוסס ‪ thread‬אחראי על הרצה בו זמנית של חלקים שונים של אותה התוכנה‪.‬‬ ‫כאן חשוב לציין שריבוי משימות בו‪-‬זמני אמיתי ניתן ליישם רק במערכות‬ ‫מבוססות מספר מעבדים (‪ ,)multiple-CPU‬כאשר לכל ‪ process‬או ‪ thread‬ישנה‬ ‫גישה בלתי מוגבלת למעבד‪.‬‬ ‫כאשר המערכת כוללת רק מעבד אחד‪ ,‬ריבוי המשימות הוא מדומה‪ ,‬זמן המעבד‬ ‫מחולק בין ה‪ threads-‬השונים‪,‬וגודלו נקבע לפי מספר פקטורים‪ ,‬כולל ה‪priority-‬‬ ‫שלהם‪.‬‬ ‫ריבוי משימות (‪ )thread‬משונה בצורה פונדמנטלית את הארכיטקטורה של‬ ‫התוכנה‪ .‬בניגוד לתוכנה בעלת ‪ thread‬אחד שמתבצעת בצורה ליניארית‪ ,‬תוכנה‬ ‫בעלת מספר ‪ threads‬כוללת אלמנטים של פרלליות‪ ,‬ולכן האתגר הוא לנהל את‬ ‫התקשורת בין ה –‪.threads‬‬

‫‪.1.7‬זמן‪-‬אמת‬ ‫מערכת נקראת מערכת זמן‪-‬אמת אם הצלחת הפעולה תלויה לא רק בנכונות‬ ‫לוגית של התוצאה‪ ,‬אלא גם בזמן ביצוע הפעולה‪.‬‬ ‫ישנם שני סוגים של מערכות זמן‪-‬אמת‪ :‬קשיחות (‪ )hard‬ומתונות (‪.)soft‬‬ ‫במערכת קשיחה אי ביצוע הפעולה הדרושה בזמן שהוקצב נחשבת לכישלון‬ ‫המערכת‪ .‬מערכות מסוג זה מתבססות על אינטראקציה מאוד קרובה עם‬ ‫חומרה‪ .‬קוצב לב הוא דוגמא טובה למערכת כזאת‪ ,‬תגובה מאוחרת תגרום‬ ‫למוות של המטופל‪.‬‬ ‫במערכות מתונות אי ביצוע הפעולה הנדרשת בזמן שהוקצב לא נחשבת לכישלון‬ ‫אלא רק מורידה את הביצועים של המערכת‪ .‬נגן מדיה שמפספס את ההצגה של‬ ‫חלק מהפריימים הוא דוגמא טובה‪.‬‬ ‫מערכת הפעלה "חלונות" אינה מערכת זמן‪-‬אמת ולכן גם כל אפליקציה שרצה‬ ‫במערכת זו אינה יכולה להיות אפליקציית זמן‪-‬אמת‪.‬‬ ‫תוכנת "‪ "Cats‬שואפת‪ ,‬במסגרת המגבלות של מערכת ההפעלה‪ ,‬להיות מערכת‬ ‫זמן‪-‬אמת‪ ,‬כאשר שימוש בריבוי המשימות הוא אחד הכלים המשמשים למטרה‬ ‫זו‪.‬‬ ‫‪.1.8‬רובוטים הָפֵטיים – ‪Haptic Devices‬‬ ‫‪ – Haptic Device‬התקן שמטרתו היא לדמות תחושה עורית‪ ,‬לדמות אפקטים של‬ ‫חיכוך‪ ,‬צמיגות‪ ,‬קשיחות וכו'‪ .‬ההתקן מפעיל כוחות מתאימים על האדם (או בעל‬ ‫חיים) שמשתמש בו וע"י כך נותן תחושה של האפקט הרצוי‪.‬‬ ‫המערכת כוללת שני רובוטים הָפֵטיים (‪ )haptic‬של חברת ‪.Sensable‬‬ ‫מטרתם של הרובוטים האלה במערכת הניסוי שונה ברוב המקרים מייעודם‬ ‫המקורי‪ ,‬במקום לדמות תחושה הרובוט מופעל ע"י התוכנה ומבצע משימות‬ ‫שונות ללא הספקת גירוי לחתול‪.‬‬ ‫לכל רובוט תפקיד משלו במערכת‪:‬‬ ‫‪ – Phantom Omni‬מתפקד כמטרה שאותה החתול צריך לתפוס‪ .‬מבצע פעולות‬ ‫כגון תזוזה למקום מסוים‪ ,‬המתנה בנקודה מסוימת‪ ,‬הדמיה של משטח ללא‬ ‫חיכוך וכו'‪.‬‬ ‫‪ – Phantom Premium‬מתפקד כמפריעה לתנועה (‪ .)Perturbatoion‬מפעיל כוחות על‬ ‫הגפה של החתול בהתאם להגדרות הניסוי‪ ,‬כגון כוח קבוע בכוון מסוים‪ ,‬כוח‬ ‫אנכי לתנועה וכו'‪.‬‬

‫‪.1.9‬משאבה‬ ‫המשאבה משמשת להזרמת אוכל (‪ )reward‬לחתול בזמן ביצוע הניסוי‪.‬‬ ‫מפרט של המשאבה מצורף לדו"ח‪.‬‬

‫המשאבה כוללת אפשרות של שליטה מרחוק‪.‬‬

‫ניתן לראות שני טרמינלים (‪ )Remote Start/Stop Input‬בצידה האחורי של‬ ‫המשאבה שמאפשרים לשלוט על הפעלה או הפסקה של המשאבה (אין אפשרות‬ ‫לשלוט על כוון או הכוח מרחוק)‪.‬‬ ‫שני הטרמינלים חוברו לכרטיס ‪ A/D‬וכך התקבלה האפשרות לשלוט על עבודת‬ ‫המשאבה מתוך התוכנה ההתנהגותית‪.‬‬ ‫החיבור נעשה לא ישירות‪ ,‬אלא דרך מעגל אלקטרו‪-‬אופטי‪.‬‬ ‫למעגל שתי מטרות‪:‬‬ ‫‪.1‬התמרת האות של כרטיס ה‪ A/D-‬להפעלת‬ ‫המשאבה (‪.)5V-on, 0V-off‬‬ ‫‪.2‬בידוד המערכת (ע"י שתי דיודות אופטיות)‪.‬‬ ‫‪Pump Control Opto‬‬ ‫‪Pulse TTL‬‬ ‫‪#4‬‬ ‫‪Pump‬‬ ‫‪Rear‬‬ ‫‪Panel‬‬

‫‪1k‬‬

‫‪Manual‬‬ ‫‪#3‬‬

‫‪2‬‬

‫‪8‬‬ ‫‪7‬‬ ‫‪6‬‬

‫‪Computer‬‬ ‫‪Control‬‬ ‫‪SW1‬‬ ‫‪SWKEY-SPDT‬‬

‫‪3‬‬

‫‪5‬‬

‫‪6N139‬‬

‫‪U1‬‬

‫‪R1‬‬

‫‪1‬‬ ‫‪6‬‬ ‫‪2‬‬ ‫‪7‬‬ ‫‪3‬‬ ‫‪8‬‬ ‫‪4‬‬ ‫‪9‬‬ ‫‪5‬‬

‫‪DB9 Female‬‬

‫‪P1‬‬

‫‪Switch C.K. 7101‬‬

‫‪.1.10‬כרטיס ‪D/A‬‬ ‫‪NI PCI-6229‬‬

‫מפרט של הכרטיס מצורף לדו"ח‪ .‬כמה מילים על ‪ A/D‬ולהזכיר שגם לכרטיס יש‬ ‫‪.API‬‬

‫כבל שמתחבר לכרטיס ‪ A/D‬מתחבר בצידו השני לקופסת חיבורים (‪SCB-68‬‬ ‫‪ )Shielded I/O connector block‬מוגנת ומותאמת להקטנת רעש‪ ,‬בעלת ‪ 68‬ערוצים‪.‬‬

‫‪Force Plates.1.11‬‬ ‫תפקידם של ‪ Force Plates‬הוא לספק מידע על מידת הלחץ שאותו מפעיל החתול‬ ‫על המשטח שעליו הוא עומד‪ ,‬וע"י כך לקבוע את מצבו של החתול ברגע נתון‬ ‫(האם נשען עם שתי הגפיים הקדמיות‪ ,‬גפה אחת‪ ,‬זז למקום לא רצוי וכו')‪.‬‬ ‫בשלב זה אין במעבדה את החומרה המתאימה ולכן גם לא קיים קוד בתוכנה‬ ‫שמטפל באירועים של החומרה הזו‪ .‬כאשר יבנו‪/‬יקנו את החומרה המתאימה‬ ‫היא תעבוד מול כרטיס ה‪.A/D-‬‬ ‫‪.1.12‬רמקולים‬ ‫חתולים הם בעלי טווח שמיעה רחב יותר מאשר בני אדם‬ ‫(חתולים‪ , Hz 45-64,000 :‬בני אדם ‪ )Hz 64-23,000‬ולכן אין צורך במכשור מיוחד‬ ‫להשמעת צלילים‪.‬‬

‫אנחנו משתמשים ברמקול מחשב סטנדרטי של חברת ‪.Creative‬‬

‫‪.2‬פרק ‪ – 3‬מבנה התוכנה ממבט של משתמש‬ ‫‪ .1.13‬מבוא‬ ‫תוכנת ‪ CATS‬מיודעת לניהול וביצוע ניסויים נוירו פיזיולוגיים התנהגותיים‬ ‫בחתולים‪.‬‬ ‫התוכנה נותנת אפשרות להרכיב מהלך ניסוי‪ ,‬מבצעת את הניסוי ע"י שליטה‬ ‫בחומרה חיצונית ורושמת את תוצאות הניסוי‪.‬‬ ‫בפרק הזה אני אתאר את התיאוריה הכללית של בנית הניסוי ואז אתן סקירה‬ ‫של ממשק המשתמש בהקשר של בניית ניסוי‪.‬‬ ‫כפי שנאמר קודם‪ ,‬התוכנה נבנתה על בסיס תוכנת ‪ Monkey‬וחלק מהשמות של‬ ‫מחלקות "הורשו" גם הם מהתוכנה הקודמת‪.‬‬ ‫במשך בניית התוכנה הגענו למסכנה שיש צורך בשמות שמתארים טוב יותר את‬ ‫התפקיד של המחלקות אשר מייצגות בלוקים אשר מרכיבים את הניסוי‪.‬‬ ‫מכיוון שההחלטה הסופית בקשר לשמות התקבלה ברגע האחרון‪ ,‬החלטנו‬ ‫לשמור על שמות המחלקות כמו שהם‪ ,‬אך מצד השני להוסיף לכל החלונות של‬ ‫ממשק המשתמש את השמות החדשים‪ .‬בשלבים הבאים של פיתוח התוכנה‬ ‫ישתנו גם השמות של המחלקות עצמן‪.‬‬ ‫‪.1.14‬תאור כללי של מבנה הניסוי (‪)Session‬‬ ‫היחידה הביצועית הכי קטנה של התוכנה היא ניסיון (‪ .)Trial‬ישנם שני שלבים‬ ‫בהגדרת ניסיון – סוג ניסיון (‪ )Trial Type‬ו‪ -‬הגדרת ניסיון (‪.)Trial Definition‬‬ ‫סוגי ניסיונות מוגדרים ע"י המתכנת בהתאם לניסיונות שנכתבו עבור התוכנה –‬ ‫המשתמש אינו משנה הגדרות ברמה זו‪.‬‬ ‫המשתמש יוצר הגדרות של ניסיונות (‪ )Trial Definitions‬מתוך הסוגי הניסיונות‬ ‫שהוגדרו ע"י המתכנת‪ .‬ניתן ליצור מספר רב של ניסיונות שונים מכל סוג‬ ‫ניסיונות‪ ,‬כאשר מהלך הניסיון יהיה קבוע אבל פרמטרים שונים (זמנים‪ ,‬מיקום‬ ‫הפנטומים‪ ,‬צלילים וכו')‪.‬‬ ‫ניסיונות מאוגדים לבלוקים (‪ .)Blocks‬בלוק יכול להכיל בתוכו סוג אחד או יותר‬ ‫של ניסיונות מסוג אחד או יותר‪ .‬בלוקים הם יחידות נוחות מאוד לבניית הניסוי‬ ‫– ניתן לשכפל אותם ולשנות את הסדר שלהם וכך להקל על שינויים במהלך‬ ‫הניסוי‪.‬‬ ‫הניסוי (‪ )Session‬מורכב מאחד או יותר בלוקים‪ ,‬המסודרים בסדר מסוים שנקבע‬ ‫מראש ע"י המשתמש‪.‬‬

‫‪Session‬‬ ‫‪Block 1‬‬ ‫‪Repeat L Times‬‬

‫‪Trial Definition A‬‬

‫‪Repeat M Times‬‬

‫‪Trial Definition B‬‬

‫‪Repeat N Times‬‬

‫‪Trial Definition A‬‬

‫‪Repeat O Times‬‬

‫‪Trial Definition C‬‬

‫‪Repeat P Times‬‬

‫‪Trial Definition B‬‬

‫‪Block 2‬‬

‫‪Block 3‬‬

‫‪Block 4‬‬

‫‪Block 5‬‬

‫פרמטרים הם הערכים שהמשתמש יכול לשנות וע"י כך להשפיע על התנהגות‬ ‫התוכנה‪ .‬דוגמא לפרמטרים היא נקודה שעליה הפאנטום צריך להגיע בתחילת‬ ‫הניסיון ‪ -‬המשתמש יכול לספק את הקואורדינאטות וכך לשנות את המיקום‬ ‫(הדרך הנכונה לשינוי פרמטרים מפורטת בהמשך)‪.‬‬ ‫כל ניסיון מכיל בתוכו הגדרה של מהלך הביצוע ותנאים להצלחה או לכישלון‬ ‫שלו‪ .‬מהלך הניסיון זהו אוסף של פקודות הניתנות לחומרה‪ ,‬כאשר הפקודות‬ ‫ניתנות בהתאם לשלב בניסיון ובהתאם לתגובת הנבדק באותו שלב‪ .‬ב‪ fig-‬ניתן‬ ‫לראות מספר דוגמאות למהלכי הביצוע של ניסיונות פשוטים יחסית‪.‬‬

Start

Reward Phantom - Start position

“Go ”cue to the cat

Wait for limb movement No

Yes

RewardPhantom - Move Away

Give Reward

Reward Phantom -Move Away

Falure

Success

Start

Reward Phantom - Start position

“Go ”cue to the cat

Wait for limb movement No

Yes

RewardPhantom - Move Away

Perturbation Phantom - Force On

Falure

Wait for Target reach No

Perturbation Phantom - Force Off Reward Phantom - Move Away

Falure

Yes Perturbation Phantom - Force Off Give Reward

RewardPhantom -Move Away

Success

‫‪.1.15‬ממשק משתמש‬ ‫האינפורמציה מהסעיף הקודם תעזור לנו להבין טוב יותר את החלקים השונים‬ ‫בממשק המשתמש‪ .‬סעיף זה יתאר איך מתבצעות למעשה הפעולות שתוארו‬ ‫בסעיף הקודם‪.‬‬ ‫ממשק המשתמש של התוכנה תוכנן כך שכל המידע יהיה זמין וכל פעולה‬ ‫שהמשתמש ירצה לבצע תהיה במרחק של לחיצת עכבר‪.‬‬

‫חלקי הממשק הדומיננטיים הם שלושת החלונות (‪ )Documents‬שמטרתם היא‬ ‫להציג מידע למשתמש (לחלון העליון ישנם גם תפקידים אחרים) והסרגל כלים‬ ‫מצידו השמאלי של המסך‪.‬‬ ‫החלון העליון‬ ‫חלון הפאנטומים‪ .‬החלון מציג את מיקום הפאנטומים וגם מאפשר לכייל‬ ‫אותם‪ .‬המשתמש יכול להפעיל או להפסיק את עדכון המיקום של‬ ‫הפאנטומים (כל פאנטום בנפרד) ובנוסף יכול לספק את תדירות העדכון‬ ‫(במילישניות)‪.‬‬

‫חלון אמצעי‬ ‫חלון סטטיסטיקת הצלחות בניסוי‪ .‬החלון מציג ‪ 4‬ערכים‪ :‬סה"כ ניסיונות‬ ‫שנעשו‪ ,‬הצלחות‪ ,‬כישלונות וכמה פעמים הניסיון הופסק באמצע ע"י‬ ‫המשתמש‪.‬‬ ‫החלון התחתון‬ ‫חלון המשתנים‪ .‬חלון זה מציג את כל המשתנים שהוגדרו עבור הניסוי ע"י‬ ‫המשתמש‪.‬‬ ‫סרגל כלים‬ ‫סרגל הכלים הוא מרכז השליטה העיקרי של התוכנה‪ .‬בעזרת הכפתורים‬ ‫שעליו ניתן לבנות את מהלך הניסוי‪ ,‬להריץ את הניסוי‪ ,‬להפסיק אותו ולבצע‬ ‫פעולות נוספות אחרות כגון הפעלה ידנית של צליל או הפעלת משאבת‬ ‫התגמול בצורה ידנית בכל שלב של הניסוי‪.‬‬ ‫‪Start Session‬‬ ‫‪Run Section‬‬ ‫‪Stop Session‬‬ ‫‪Parameters‬‬

‫‪Blocks‬‬ ‫‪Build Section‬‬ ‫‪Trial Definitions‬‬

‫‪Trial Types‬‬

‫‪Manual Pump‬‬

‫‪Manual Control‬‬ ‫‪Section‬‬

‫‪Manual Sound‬‬

‫‪.i‬‬

‫ממשק בניית מהלך הניסוי‬

‫תהליך בניית מהלך הניסוי (‪ )Session‬מורכב ממספר שלבים‪:‬‬ ‫‪.1‬הגדרת סוג הניסיון (‪ )Trial Type‬בקוד ע"י המתכנת‬ ‫(בהמשך) והוספתו לרשימת הניסיונות‪.‬‬ ‫‪.2‬הרכבת הגדרות הניסיונות (‪.)Trial Definitions‬‬ ‫‪.3‬הרכבת בלוקים (‪ )Blocks‬מהגדרות של ניסיונות‪.‬‬ ‫‪.4‬הוספת הפרמטרים (‪ )Parameters‬לניסוי‪.‬‬ ‫עבור כל שלב ברשימה לעיל ישנו כפתור על סרגל הכלילים הראשי‪ ,‬אשר פותח‬ ‫תיבת דו‪-‬שיח אשר מאפשרת לבצע את הפעולות הרצויות‪.‬‬ ‫לבדוק האם לשינוי של פרמטרים וכו' בזמן הרצה יש משמעות ולציין את זה‬ ‫איפשהו‬

‫‪.1‬כפתור ה‪( Trials Types-‬‬

‫) פותח את תיבת הדו‪-‬שיח הבאה‪:‬‬

‫כאן ניתן לראות את רשימת ה‪ Trial Types-‬הקיימים כרגע בתוכנה (בדוגמא זו‬ ‫רואים את ה‪ .)Taming Trial-‬שלושת הכפתורים בחלון זה נותנים את האפשרות‬ ‫להוסיף‪ ,‬לערוך או למחוק את הניסיון (כפתורים ‪ Edit‬ו‪ Delete -‬הופכים להיות‬ ‫פעילים רק כאשר נבחר את הניסיון שאותו נרצה לערוך או למחוק)‪.‬‬ ‫לחיצה על כפתור ה‪ Add-‬תפתח חלון דו‪-‬שיח של הוספת ניסיון חדש‪:‬‬

‫בחלון זה ניתן להוסיף את שם הניסיון בלבד‪ ,‬את שאר הפרטים מוסיפים ע"י‬ ‫תיבת דו‪-‬שיח ‪:Edit‬‬

‫בחלון זה מוסיפים את שם הפונקציה שמפעילה את הניסיון ואת כל הפרמטרים‬ ‫שלה‪.‬‬ ‫הוספת הניסיון תעשה ע"י המתכנת שכותב את הפונקציה ורוצה להפוך אותה‬ ‫לזמינה לשימוש‪.‬‬

‫‪.2‬כפתור ה‪( Trial Definitions -‬‬ ‫את הניסיונות‪:‬‬

‫) פותח את תיבת הדו‪-‬שיח שבה מגדירים‬

‫בחלון זה יש לנו אפשרות להוסיף‪ ,‬לערוך‪ ,‬למחוק או לשכפל את אחד‬ ‫מהניסיונות (במקום ליצור חדש)‪.‬‬ ‫לחיצה על כפתור ה‪ Add-‬תפתח את תיבת דו‪-‬שיח הבאה‪:‬‬

‫בחלון זה יש לנו אפשרות להגדיר סוג חדש‪ .‬הניסיון מבוסס על סוג ניסיון‬ ‫כלשהו בתוספת פרמטרים מיוחדים‪ .‬בתיבה זו ניתן לבחור את סוג הניסיון‬ ‫שעליו נתבסס‪ ,‬להוסיף פרמטרים ולתת שם ו‪ ID -‬לניסיון חדש‪.‬‬ ‫‪.3‬כפתור ה‪( Blocks-‬‬

‫) פותח את תיבת הדו‪-‬שיח שבה מוגדרים הבלוקים‪.‬‬

‫בתיבה זו ניתן לראות אילו בלוקים מוגדרים עבור ה‪ Session-‬הנוכחי‪ ,‬מהו‬ ‫סדר הביצוע שלהם בזמן ההרצה והאם הם פעילים (אם בלוק מסוים מוגדר‬ ‫כ‪ Not Active-‬הוא לא יבוצע בזמן הרצת ה‪.)Session-‬‬ ‫לחיצה על כפתור ה‪ Add-‬תפתח את תיבת דו‪-‬שיח שבה ניתן להוסיף בלוק‬ ‫חדש ע"י הוספת השם שלו ולחיצה על כפתור ‪.Ok‬‬

‫לחיצה על כפתור ה‪ Edit-‬תפתח את תיבת דו‪-‬שיח שבה ניתן לערוך את‬ ‫הבלוק‪.‬‬

‫ברשימה מופיעים כל ה‪ Trials-‬שהוספנו לבלוק הזה‪ ,‬מספר הפעמים שנבצע‬ ‫את הניסיון בזמן ההרצה והאם לבצע אותו או לא (האם הוא ‪.)Active‬‬ ‫בחירה של אחד הניסיונות מהרשימה ולחיצה על ‪ Edit‬תפתח תיבת דו‪-‬שיח‬ ‫שבה ניתן לשנות את מספר הפעמים שהניסיון יבוצע‪:‬‬

‫לחיצה על כפתור ‪ Add‬תיפתח תיבת דו‪-‬שיח שבה ניתן לבחור את הניסיון‬ ‫שנרצה להוסיף לבלוק‪ ,‬מתוך רשימה של ניסיונות מוגדרים‪:‬‬

‫‪.4‬כפתור ה‪ ) ( Parameters-‬פותח את תיבת הדו‪-‬שיח שבה ניתן להוסיף‬ ‫פרמטרים ולשנות את ערכם‪:‬‬

‫כמו בכל שאר החלונות‪ ,‬לחיצה על כפתור ה‪ Add-‬תפתח תיבת דו‪-‬שיח שבה‬ ‫ניתן להוסיף פרמטר חדש‪ .‬לחיצה על כפתור ‪ Edit‬תיתן אפשרות לשנות‬ ‫פרמטר קיים‪.‬‬

‫‪.3‬פרק ‪ – 4‬הקוד‬ ‫‪.1.16‬מבוא‬ ‫תוכנת ‪ Cats‬התבססה בראשית על קוד של תוכנה שמשמשת לניהול ניסויים‬ ‫בקופים – ‪ .Monkey‬התכנון הראשוני היה לבצע שינויים קלים בתוכנה זו‬ ‫ולהכניס אותה לשימוש‪ ,‬אך אחרי בחינה של יכולות התוכנה התברר שהיא‬ ‫עובדת עם כלים שונים ולמרות הדמיון הרעיוני הרב האימפלמנטציה של רוב‬ ‫חלקי התוכנה לא התאימה לצרכים שלנו‪.‬‬ ‫להמשיך‪.....‬‬ ‫‪.1.17‬מבט כללי על הקוד‬ ‫כאמור התוכנה מחלקת את המשימות שלה למספר ‪ ,threads‬שרצים במקביל‬ ‫וע"י כך מושגת היעילות המרבית בניצול משאבי המערכת‪.‬‬ ‫להוסיף הסבר בהתחלה של ‪ OO‬ושל ‪( MFC‬עבור כל מושג שאני משתמש בו)‬ ‫להוסיף גם תאור של ‪UINT‬‬ ‫‪ CatsDoc‬היא המחלקה (‪ )class‬הראשית של התוכנה‪ ,‬היא זו שמגיבה לפעולות‬ ‫של המשתמש (כגון לחיצה על כפתור) והיא זו שמפעילה את ההליכים (‪.)threads‬‬ ‫ישנם ‪ 3‬הליכים בתוכנה‪:‬‬ ‫;)‪1. UINT TrialThread(LPVOID param‬‬ ‫;)‪2. UINT PhantomsThread(LPVOID param‬‬ ‫;)‪3. UINT UtilityThread(LPVOID param‬‬

‫* ‪.UINT- Unsigned Integer‬‬ ‫* ‪ – LPVOID‬מצביע ‪ 32‬ביט לסוג (‪ )type‬לא מוגדר (ולכן יכול להצביע לכל סוג של‬ ‫אובייקט)‪.‬‬ ‫שלושת ההליכים מוגדרים בקובץ נפרד הנקרא ‪.Threads.cpp‬‬ ‫‪TrialThread.1‬‬

‫הליך זה אחראי על קומפילציה של כל הפרמטרים ומהלך הניסוי‬ ‫והרצתם בסדר הרצוי‪.‬‬ ‫‪PhantomsThread.2‬‬ ‫הליך זה משמש להפעלת הפאנטום (כאשר יהיו שני פאנטומים יהיה‬ ‫צורך בהליך נוסף זהה)‪.‬‬ ‫‪UtilityThread.3‬‬ ‫תפקידו היחיד של הליך זה הוא "לחכות" לאות סיום של הניסוי‬ ‫ולעצור את ה‪.TrialThread-‬‬

‫‪CatsDoc‬‬

‫‪UtilityThread‬‬

‫‪PhantomsThread‬‬

‫‪TrialThread‬‬

‫שלושת ההליכים מקבלים כפרמטר מצביע (‪ )pointer‬ל‪ CatsDoc-‬ולכן יש להם‬ ‫גישה לכל המשאבים של המחלקה הזו‪.‬‬ ‫תקשורת בין שני ההליכים ‪ PhatomsThread‬ו‪ TrialThread-‬מתבצעת ע"י מחלקה‬ ‫שנקראת ‪ .PhantomMessenger‬אובייקט של מחלקה זו מוגדר ב‪.CatsDoc-‬‬ ‫‪CatsDoc‬‬ ‫‪Communication‬‬

‫‪Communication‬‬

‫‪PhantomsThread‬‬

‫‪PhantomMessenger‬‬

‫‪TrialThread‬‬

‫‪ PhantomsThread‬ו‪ UtilityThread -‬מופעלים ב‪ InitializeDocument -‬של המחלקה‬ ‫‪ ,CatsDoc‬ז"א הם קיימים במשך כל זמן פעילות התוכנה‪ ,‬מרגע ההרצה ועד‬ ‫הסיום (הם לא מופסקים בשום מקום)‪.‬‬ ‫‪ TrialThread‬מופעל רק כאשר המשתמש לוחץ על כפתור ההרצה של הניסוי‬ ‫ומופסק כאשר הניסוי נגמר או כאשר המשתמש לוחץ על כפתור העצירה‪.‬‬ ‫המשך הפרק נכנס לפרטי הקוד‪ ,‬ומכוון שישנם חלקי קוד שמופעלים במקביל‬ ‫עומדת בפני משימה לא קלה בלתאר אותו‪ .‬לסדר שבו יתוארו המחלקות בהמשך‬ ‫יש משמעות והוא מנסה להעביר צורת מחשבה מסוימת‪ ,‬שלדעתי תסייע בהבנת‬ ‫המבנה של הקוד בפרט והתוכנה בכלל‪.‬‬ ‫כאמור ‪ threads‬מחלקים את המשימות של התוכנה למספר חלקים שרצים‬ ‫במקביל‪ .‬בשלב הראשון אתאר את המחלקות הקשורות לבניית מהלך הניסוי‪.‬‬ ‫תהליך בניית מהלך הניסוי יוצר תבנית מסוימת (לפי הגדרות המשתמש) ולפיה‬ ‫מריצה את הניסיונות השונים‪ ,‬ולכן בשלב השני אתאר את המחלקה ‪Trial‬‬ ‫שממנה מורשים כל המחלקות שמגדירות ניסיונות וגם ‪ TamingTrial‬שהיא‬ ‫מחלקה שמורשת מ‪.Trial-‬‬ ‫מכוון שמהלך הניסיון מורכב בעיקרו מהפעלה של חומרה שונה‪ ,‬בשלב השלישי‬ ‫אתחיל לתאר את המחלקות שקשורות לחלקי חומרה שונים ואיך מתבצעת‬ ‫התקשורת בין ה‪ Trial-‬והחומרה‪.‬‬

‫‪.1.18‬תהליך בניית מהלך הניסוי‬ ‫תהליך זה מורכב מאסיפת המידע מהמשתמש‪ ,‬קומפילציה והרצת הניסיונות (‬ ‫‪ )trials‬לפי הסדר הנתון‪ .‬במהלך ההרצה נאסף הקלט מהפאנטומים ומקורות‬ ‫אחרים ומתקבלת ההחלטה על הצלחתו של הניסיון ועל המשך ה‪.session-‬‬ ‫המחלקה ‪Trials‬‬ ‫קובץ ‪ Trials.cpp‬מגדיר חמש מחלקות שתפקידן להיות מיכלים (‪)containers‬‬

‫למידע על מהלך הניסוי‪ .‬המחלקות הן‪:‬‬ ‫‪class CTrialParam:public CObject‬‬ ‫‪class CTrialList:public CObject‬‬ ‫‪class CTrialDef:public CObject‬‬ ‫‪class CTrialOrder:public CObject‬‬ ‫‪class CTrialGroup:public CObject‬‬

‫)‪1‬‬ ‫)‪2‬‬ ‫)‪3‬‬ ‫)‪4‬‬ ‫)‪5‬‬

‫חמשת המחלקות מורשות מ‪ CObject-‬שהיא מחלקה בסיסית לרוב המחלקות‬ ‫של ‪ MFC‬ומורישה מספר תכונות בסיסיות שימושיות למחלקות כגון‬ ‫סריאליזציה (‪ .)Serialization‬לפי שמות המחלקות ניתן לראות שכל אחת מהן‬ ‫אחראית על מידע מסוג שונה‪ ,‬כגון פרמטרים של הניסיון‪ ,‬הגדרת הניסיון וכו'‪.‬‬ ‫המחלקה הראשית שמוגדרת בקובץ זה היא‪:‬‬ ‫להזכיר שוב את השמות החדשים‬ ‫‪class CTrials:public CObject‬‬

‫היא מחזיקה את כל המידע של הניסוי (‪ )session‬הנוכחי‪ ,‬כאשר היא מחזיקה‬ ‫אובייקטים מחמשת המחלקות כ‪( .data members-‬למעשה כל ה‪data members-‬‬ ‫מוגדרים מסוג ‪ CObject‬וה‪ casting-‬מתבצע בכל פעם שנגשים למידע)‪ .‬מחלקה זו‬ ‫שומרת בנוסף ‪ data members‬שמחזיקים פלט ביניים של המהדר (‪.)compiler‬‬

class CTrials:public CObject { DECLARE_SERIAL(CTrials); public: virtual void Serialize(CArchive& ar); CObArray m_TrialParam; //info from Param dialog box CObArray m_TrialOrder; //info from Order dialog box CObArray m_TrialList; //info from List dialog box CObArray m_TrialDef; //info from TrialDef dialog box CObArray m_code_seg; //array of objects returned from compiler - code CObArray m_data_seg; //array of objects returned from compiler - data CObArray m_fun_tab; //holds constant function list from functions.cpp CObArray m_event_tab; // holds constant events declared at CCatsDoc.cpp CUIntArray m_seq_tab; //holds sequence of all trials - returned from gen_seq() CUIntArray m_startGroups; //also returned from gen_seq() CTrials(); ~CTrials(); //calls clear_all() CObArray & GetDef(); CObArray & GetList(); CObArray & GetOrder(); CObArray & GetParam(); CObArray & GetEvents(); CTextFile *txtTrialsData; void WriteToText(CTextFile &txtFile); // writes all class data to text file void ReadFromText(CTextFile &txtFile); //reads all data from text file void clear_all(); void clear(); void compile(); void gen_seq(); void run(int n); };

‫ שמטרתן היא להכין את המידע‬,‫למחלקה מוגדרות גם מספר פונקציות‬ .‫ תפקידן יובהר בהמשך‬.‫שבמחלקה ולהעביר אותו לעיבוד ע"י המהדר‬ .CatsDoc-‫אובייקט מסוג זה נמצא ב‬ Compile ‫המחלקה‬

‫ שתפקידה להדר‬compile ‫ מכיל בתוכו הגדרה של מחלקה‬compile.cpp ‫קובץ‬ .‫ולהריץ את הניסוי‬ ‫ ולכן לא אכנס לפרטי הקומפילציה ואפרט‬Monkey ‫מחלקה זו מיובאת מהתוכנה‬ .‫רק מספר פונקציות שאיתן אני מתממשק‬ compile(); gen_seq(); run();

‫() מבצעת את הקומפילציה הבסיסית הכוללת בדיקת תאימות‬compile ‫פונקציה‬ ‫ פונקציה זו קוראת לשלוש פונקציות אחרות‬.‫המידע שהוזן ע"י המשתמש‬ :‫המוגדרות באותה המחלקה‬

‫;)(‪lexical‬‬ ‫;)(‪syntax‬‬ ‫;)(‪semantic‬‬

‫שמות הפונקציות מתארות את הבדיקות שהן מבצעות‪.‬‬ ‫‪ )(compile‬מחזירה שתי מחרוזות (‪ )lists‬מסוג ‪ CObject‬לאובייקט מסוג ‪.CTrials‬‬ ‫פונקציה ‪ )(gen_seq‬מקבלת כקלט את הפלט של ‪ )(compile‬ומחזירה שתי‬ ‫מחרוזות של מספרים (‪ )integers‬המקודדים את סדר הביצוע של הניסוי‪.‬‬ ‫פונקציה ‪ )(run‬קוראת למצביעים (‪ )pointers‬לפונקציות המתאימות וכך מריצה‬ ‫את הניסוי‪.‬‬ ‫מהלך האירועים בהפעלת הניסוי‬ ‫שתי המחלקות שתוארו לעיל הן השחקניות העיקריות של הפעלת הניסוי (אך‬ ‫לא היחידות)‪.‬‬ ‫‪ TrialThread‬מופעל בפונקציה ‪ )(CCatsDoc::OnStart‬שנקראת כאשר המשתמש‬ ‫לוחץ על לחצן ה‪.Start-‬‬ ‫ההליך ‪ TrialThread‬מבצע מספר פעולות לפי הסדר‪:‬‬ ‫‪.1‬מאפס ומנקה את כל המשתנים הזמניים שיכולים להכיל מידע‬ ‫מהרצה קודמת של הניסוי‪.‬‬ ‫‪.2‬קורא לפונקציה ‪ )(compile‬של אובייקט מסוג ‪( CTrials‬והיא‬ ‫קוראת ל‪ )(compile -‬של המהדר)‪.‬‬ ‫‪.3‬קורא לפונקציה ‪ )(gen_seq‬של אובייקט מסוג ‪( CTrials‬והיא‬ ‫קוראת ל‪ )(gen_seq -‬של המהדר)‪.‬‬ ‫‪.4‬נכנס ללולאה ועבור כל איבר במחרוזת ‪m_seq_tab (member‬‬ ‫‪ variable‬של אובייקט מסוג ‪ CTrials‬שמאוכלס ע"י הרצת‬ ‫פונקצית ‪ )(gen_seq‬של המהדר) קורא לפונקצית ‪ )(run‬של‬ ‫אובייקט מסוג ‪( CTrials‬שיקרא לפונקצית ‪ )(run‬של המהדר)‪.‬‬ ‫‪.5‬בכל סבב של הלולאה אחרי הקריאה ל‪ )(run-‬נאסף כל המידע‬ ‫שהתקבל בזמן ההרצה ובהתאם להצלחה או כשלון של הניסיון‬ ‫מתקבלת ההחלטה האם להמשיך או להפסיק את ביצוע‬ ‫הניסוי‪.‬‬ ‫‪.6‬מתבצע חישוב של זמן ‪ )ITI (Inter Trial Interval‬ונקראת פונקצית‬ ‫‪ )Sleep(t‬ש"מרדימה" את ההליך לזמן ה‪.ITI-‬‬

‫‪ .1.19‬הגדרת הניסיון (‪)Trial‬‬ ‫תפקידה של מחלקה זו‪ ,‬והמחלקות שמורשות ממנה‪ ,‬לתאר את מהלך הניסיון‬ ‫ע"י שליחת אירועים לחומרה וקבלת פידבק ממנה‪.‬‬ ‫כל ‪ Trial‬שיכול להיות מוגדר בתוכנה יהיה מורש ממחלקת האם ‪ Trial‬שמוגדרת‬ ‫בקובץ ‪.Trial.cpp‬‬ ‫מחלקת האם ‪ Trial‬מגדירה את הפרמטרים האוניברסאליים עבור כל ניסיון‬ ‫שיכול להיות מורש ממנה‪ .‬פרמטרים מיוחדים יכולים להיות מוגדרים במחלקת‬ ‫הבת‪.‬‬ ‫הפונקציה שאחראית על קריאת הערכים של הפרמטרים שהוזנו ע"י המשתמש‬ ‫נקראת‪ .)(getParams :‬מחלקת הבת שתגדיר פרמטרים מיוחדים תצטרך להגדיר‬ ‫פונקציה זו מחדש ולקרא לפונקציה של מחלקת האם כדי לקרא לכל‬ ‫הפרמטרים‪.‬‬ ‫)(‪void Trial::getParams‬‬ ‫{‬ ‫;)‪CParam* param=(CParam*)in_param.GetAt(0‬‬ ‫;)‪if (param->type==CO_NUMBER) m_TargetStartX=atof(param->name‬‬ ‫;)‪param=(CParam*)in_param.GetAt(1‬‬ ‫;)‪if (param->type==CO_NUMBER) m_TargetStartY=atof(param->name‬‬ ‫;)‪param=(CParam*)in_param.GetAt(2‬‬ ‫;)‪if (param->type==CO_NUMBER) m_TargetStartZ=atof(param->name‬‬ ‫;)‪param=(CParam*)in_param.GetAt(3‬‬ ‫;)‪if (param->type==CO_NUMBER) m_ForceStart=atof(param->name‬‬ ‫)‪………..(more parameters‬‬ ‫}‬

‫* המחלקה ‪ CParam‬מוגדרת ב‪.compile.cpp-‬‬ ‫מחלקת האם ‪ Trial‬כוללת את הפונקציה ‪ )(runTrial‬שתכלול את מהלך הביצוע‬ ‫של הניסיון‪ .‬פונקציה זו היא וירטואלית טהורה (‪ )pure virtual‬מכוון שאין הגדרה‬ ‫ברירת מחדל לביצוע הניסיון וכל מחלקה שתהיה מורשת ממחלקת האם תהיה‬ ‫חייבת להגדיר את מהלך הביצוע של הניסיון‪.‬‬ ‫;‪virtual void runTrial(){}; // = 0‬‬

‫בנוסף‪ Trial ,‬מגדיר מספר פונקציות שמעדכנות משתנים שמקפיצות אירועם‬ ‫הקשורים להצלחה או כשלון של הניסיון‪.‬‬ ‫‪protected:‬‬ ‫‪virtual void successfulTrial(); //set Trial Successful‬‬ ‫‪virtual void trialFail(int catsEventID); //set Trial Failed‬‬ ‫)…‪void sendCatsEvent(int catsEventID); //Send Current Event (like: cat started eating‬‬

‫‪TamingTrial‬‬

‫מחלקת הבת ‪ TamingTrial‬היא מחלקה שמורשת מ‪ Trial-‬ומגדירה מהלך ניסיון‬ ‫של אילוף החתול‪ .‬בניסיון זה משתתף רק פאנטום אחד‪ ,‬מכוון שרוצים לאלף‬ ‫את החתול להושיט את הגפה ולא להפריע לו בתנועה‪.‬‬

‫לניסיון זה אין משתנים שמיוחדים רק לו‪ ,‬ולכן אין צורך עקרוני בהגדרה‬ ‫מחודשת של פונקצית ‪ ,)(getParams‬אבל היא מוגדרת כדי לשמור על המבנה‬ ‫הבסיסי של המחלקות מסוג ‪ .Trial‬פונקציה זו רק קוראת לפונקצית ‪)(getParams‬‬ ‫של ‪.Trial‬‬ ‫)(‪void TamingTrial::getParams‬‬ ‫}‬ ‫;)(‪Trial::getParams‬‬ ‫{‬

‫המחלקה צריכה להגדיר מחדש את הפונקציה הוירטואלית הטהורה ‪)(runTrial‬‬ ‫של מחלקת האם ‪.Trial‬‬ ‫הקוד בנוי על ראיון של שליחת הוראה לפעולה (הפעלת פאנטום‪ ,‬צליל‪ ,‬כרטיס‬ ‫‪ A/D‬או חומרה אחרת) והמתנה עד לקבלת אות של סיום הפעולה‪.‬‬ ‫‪//Phantom moves to starting position‬‬ ‫_ ‪p_msgr->MoveToPoint(m_TargetStartX,‬‬ ‫;)‪m_TargetStartY,m_TargetStartY,m_ForceStart,m_TimeInitialPosition‬‬ ‫)‪while(true‬‬ ‫{‬ ‫)‪if(WaitForSingleObject(p_msgr->ph_finished_event, 0) == WAIT_OBJECT_0‬‬ ‫{‬ ‫;‪break‬‬ ‫}‬ ‫;)‪Sleep(1‬‬ ‫}‬

‫הפעלת הפאנטום‬.1.20 Phantoms)( ‫ שמשווק עם הפאנטומים‬API-‫ משמשת כממשק ל‬Phantom ‫המחלקה‬ ., OpenHaptics 2.0 toolkit ‫המחלקה נבנתה כך שתהיה אפשרות להתייחס לפאנטום כאל אובייקט שיכול‬ ‫לבצע פעולות שונות (בניגוד לגישה של פונקציה אחת שיודעת לבצע את כל‬ ‫ במקרה של צורך‬.‫ ובכך ניתן לבנות בקלות מהלכי ביצוע שונים‬,)‫הפעולות‬ .‫בהוספת "יכולת" כלשהי כל מה שנדרש הוא להוסיף פונקציה נוספת למחלקה‬ class Phantom } public: Phantom(int p_num); virtual ~Phantom(); void StartFriction(HDdouble gain, HDdouble magnitude); //friction effect void StartSpring(HDdouble gain, HDdouble magnitude, _ hduVector3Dd anchor ); //spring effect void StartViscosity(HDdouble gain, HDdouble magnitude); //viscosity effect void StartConstForce(HDdouble gain, HDdouble magnitude, _ hduVector3Dd direction); //constant force effect void StartPointMass(); //point mass effect void StartFrictionlessPlane(hduVector3Dd point, double stiff); //Frictionless plane effect void StartAntiGrav(); //Antigravity effect void EndFriction(); void EndSpring(); void EndViscosity(); void EndConstForce(); void EndPointMass(); void EndFrictionlessPlane(); void EndAntiGrav(); hduVector3Dd GetPosition(); //return position of the current phantom hduVector3Dd GetForce(); //return force of the current phantom HDboolean Calibrate(); private: void initHL(HHD hHD, HHLRC &hHLRC);

// Initialize an HL rendering context for a //particular device instance void initHD(HDstring pConfigName, HHD &m_hHD); //Initialize an HD device instance bool b_calibrated; void SetCalibration(bool val); bool GetCalibration(); void MakeCurrent(); HDstring p_name; HLuint friction_force; HLuint spring_force; HLuint viscous_force; HLuint constant_force; HLuint pointmass_force; HLuint frictionless_plane_force; PointMass *pointMass; FrictionlessPlane * frictionlessPlane; };

‫) מקבל‬constructor( ‫ הבונה של המחלקה‬,‫המחלקה אינה אוניברסאלית לגמרי‬ ‫) והם אלה שקובעים את הזהות של הפאנטום (ז"א שכרגע‬2 ‫ או‬1 ‫פרמטר (ערכים‬ .)‫התוכנה יכולה להשתמש רק בשני פאנטומים‬ Phantom::Phantom(int p_num) { switch(p_num){ case 1: initHD("PHANToM 1", hHD1); initHL(hHD1, hHLRC1); break; case 2: initHD("PHANToM 2", hHD2); initHL(hHD2, hHLRC2); break; default: this.~Phantom(); } //hlGenEffects - Generates unique identifiers for effects that //may be used with the hlStartEffect function friction_force = hlGenEffects(1); spring_force = hlGenEffects(1); viscous_force = hlGenEffects(1); constant_force = hlGenEffects(1); pointmass_force = hlGenEffects(1); frictionless_plane_force = hlGenEffects(1); //create an object of custom effect frictionlessPlane = new FrictionlessPlane(); }

API-‫כוחות מובנים ב‬ ‫ ולכן אין צורך‬,‫ של הפאנטומים מספק מספר כוחות מובנים סטנדרטיים‬API-‫ה‬ :‫ צורת השימוש היא‬.‫ אלא ניתן להשתמש בהם‬,‫להגדירם מחדש‬ void Phantom::StartFriction(HDdouble gain, HDdouble magnitude) { MakeCurrent(); //make the phantom current hlBeginFrame(); //enter the rendering block hlEffectd(HL_EFFECT_PROPERTY_GAIN, gain); //set force gain hlEffectd(HL_EFFECT_PROPERTY_MAGNITUDE, magnitude); //set force magnitude hlStartEffect(HL_EFFECT_FRICTION, friction_force); //set force type hlEndFrame(); //exit rendering block (send to phantom) } void Phantom:: EndFriction () { MakeCurrent(); hlBeginFrame(); hlStopEffect(friction_force); //stop effect hlEndFrame(); }

)Custom Forces( ‫כוחות מוגדרים בצורה מיוחד‬

‫ של הפאנטומים נותן אפשרות להגדיר כוחות מיוחדים ומתאר צעדים‬API-‫ה‬ ‫ פונקציות שמגדירות את‬3 ‫ לצורך הגדרת כוח מיוחד מגדירים‬.‫לכתיבתם‬ .‫ המהלך והסיום של אפקט הכוח המיוחד‬,‫ההתחלה‬ ‫אפקט הכוח המיוחד שמוגדר בתוכנה הוא משטח ללא חיכוך (הכוח יתואר‬ .)‫בהמשך‬ :Phantom ‫הפונקציה להפעלת אפקט הכוח המיוחד במחלקה‬ void Phantom::StartFrictionlessPlane(hduVector3Dd point, double stiff) { frictionlessPlane->SetParameters(point,stiff); MakeCurrent(); hlBeginFrame(); hlCallback(HL_EFFECT_COMPUTE_FORCE, (HLcallbackProc) _ FrictionlessPlane::computeForceCB, frictionlessPlane); hlCallback(HL_EFFECT_START, (HLcallbackProc) _ FrictionlessPlane::startEffectCB, frictionlessPlane); hlCallback(HL_EFFECT_STOP, (HLcallbackProc) _ FrictionlessPlane::stopEffectCB, frictionlessPlane); hlStartEffect(HL_EFFECT_CALLBACK, frictionless_plane_force); hlEndFrame(); }

‫שלושת הפונקציות הדרושות מוגדרות במחלקה נפרדת הנקראת‬ ‫ אבל‬,‫ אינו מחייב את הכוח להיות מוגדר כמחלקה‬API-‫ ה‬.FrictionlessPlane .)‫הגדרה כזו מאפשרת טיפול יותר נוח באפקט (כגון אתחול‬ FrictionlessPlane ‫המחלקה‬

‫המחלקה מגדירה את שלושת הפונקציות הדרושות להפעלת האפקט הרצוי‬ .‫ובנוסף את כל המשתנים הפנימיים הדרושים ליצירת האפקט‬ class FrictionlessPlane { public: FrictionlessPlane(); //default constructor FrictionlessPlane(hduVector3Dd point, double stiff);//with parameters SetParameters(hduVector3Dd point, double stiff); //set parameters virtual ~FrictionlessPlane(); //destructor //functions required for effect rendering static void HLCALLBACK computeForceCB(HDdouble force[3], _ HLcache *cache, void *userdata); static void HLCALLBACK startEffectCB(HLcache *cache, void *userdata); static void HLCALLBACK stopEffectCB(HLcache *cache, void *userdata); private: hduVector3Dd m_position; hduVector3Dd m_velocity; HDdouble m_kStiffness; // Stiffnes, i.e. k value, of the plane. //Higher stiffness results in a harder surface. hduVector3Dd m_point_in_space; //point defines 3 perpendicular surfaces (by axis) hduVector3Dd m_direction_flag; //defines which of 3 surfaces to use and the direction //only one value is not zero, possible values -1,0,1 };

:computeForce ‫יצירת אפקט הכוח מתרחשת בפונקצית‬

void FrictionlessPlane::computeForceCB(HDdouble force[3], HLcache *cache, void *userdata) } FrictionlessPlane *pFrictionlessPlane = static_cast(userdata); // Get the current proxy position from the state cache. // Note that the effect state cache is maintained in workspace coordinates, // so we don't need to do any transformations in using the proxy // position for computing forces hduVector3Dd PhantomPosition; hlCacheGetDoublev(cache, HL_PROXY_POSITION, PhantomPosition); hduVector3Dd x; //F=kx hduVector3Dd f(0,0,0); //returned force double PenetrationDistance; for(int i=0; i<3; i++) //try each possible plane (3 possibilities) { if(pFrictionlessPlane->m_direction_flag[i] == 0) continue; //no plane if ((PhantomPosition[i] <= pFrictionlessPlane->m_point_in_space[i] && pFrictionlessPlane->m_direction_flag[i] > 0) ||(PhantomPosition[i] > pFrictionlessPlane->m_point_in_space[i]) &&(pFrictionlessPlane->m_direction_flag[i] < 0)) { // Create a force vector repelling the user from the plane proportional // to the penetration distance, using F=kx where k is the plane // stiffness and x is the penetration vector. Since the plane is // oriented at the Y=0, the force direction is always either directly // upward or downward, i.e. either (0,1,0) or (0,-1,0); PenetrationDistance =fabs(fabs(PhantomPosition[i]) – _ fabs(pFrictionlessPlane->m_point_in_space[i])); //relative to plane // Hooke's law explicitly: x[i] = PenetrationDistance*(pFrictionlessPlane->m_direction_flag[i]); f[i] = (pFrictionlessPlane->m_kStiffness)*x[i]; }//end if }//end for // Send the force to the device force[0] = f[0]; force[1] = f[1]; force[2] = f[2]; {

‫ניתן לראות שהפונקציה מאוד גמישה ומאפשרת (ע"י שינוי הפרמטרים) להגדיר‬ ‫) ולכל סוג ניתן לספק אחד משני‬z-x ‫ ציר‬,y-z ‫ ציר‬,x-y ‫ סוגי משטחים (ציר‬3 .)‫ סוגים של משטחים‬6 ‫כוונים (סה"כ‬ ‫ ולכן הבונה של‬,‫הגמישות הזו לא מנוצלת כרגע בתוכנה כתוצאה מחוסר צורך‬ ‫המחלקה מגדיר את הכוון ולא מקבל את הפרמטר מהמשתמש (כמובן שכאשר‬ .)‫ השינוי יהיה כל יחסית‬,‫יהיה הצורך‬

‫‪PhantomThread‬‬

‫זהו ההליך שמפעיל את הפאנטום (כאשר יתווסף פאנטום נוסף לתוכנה‪ ,‬יהיה‬ ‫צורך בהליך זהה נוסף)‪.‬‬ ‫הליך זה מופעל‪ ,‬בניגוד לשני ההליכים האחרים‪ ,‬מרגע שהתוכנה מתחילה לרוץ‬ ‫ומופסק ביחד עם סיום התוכנה‪.‬‬ ‫ההליך נכנס ללולאה ומחקה לאירועים שמגיעים מהליך אחר (‪)TrialThread‬‬ ‫ומבצע משימות בהתאם לאירועים אלה‪.‬‬ ‫‪case(WAIT_OBJECT_0+1): //Frictionless Plane‬‬ ‫_ ‪ph_ptr1->StartFrictionlessPlane(p_msgr->m_vSurfacePoint,‬‬ ‫;)‪p_msgr->m_dSurfaceStiffness‬‬ ‫)‪while (EventCurT-EventStartTm_dTimeToReachTarget‬‬ ‫{‬ ‫‪//get phantoms position‬‬ ‫;)(‪CSec.Lock‬‬ ‫‪//update the current location‬‬ ‫;)(‪p_msgr->m_vPhCurLocation=ph_ptr1->GetPosition‬‬ ‫;)(‪CSec.Unlock‬‬ ‫)‪if(WaitForSingleObject(p_msgr->ph_stop_event, 0)==WAIT_OBJECT_0‬‬ ‫{‬ ‫‪break;//leave if get stop event‬‬ ‫}‬ ‫‪Sleep(1); //less processor usage‬‬ ‫;)(‪EventCurT = timeGetTime‬‬ ‫}‬ ‫;)(‪ph_ptr1->EndFrictionlessPlane‬‬ ‫;)(‪p_msgr->SignalPhFinishedTask‬‬ ‫;‪ph_todo_ev_occured= WAIT_TIMEOUT‬‬ ‫;‪break‬‬

‫‪.1.21‬תקשורת בין ‪ Phantom‬ו‪Trial -‬‬ ‫המחלקה ‪ PhantomMessanger‬מאפשרת העברת מידע בין שני ההליכים וכך‬ ‫הפקודות שנשלחות מההליך של ‪ Trial‬מגיעות להליך של ‪.Phantom‬‬ ‫ממבט ראשון יצירת מחלקה זו נראה מיותר מכוון שאפשר להפעיל אירועים (‬ ‫‪ )events‬וכך ‪ Trial‬יוכל להפעיל את ה‪ ,Phantom-‬אבל אירוע לא יכול להעביר‬ ‫משתנים ולכן יצירתה של המחלקה היה נחוץ‪ .‬בנוסף תפקידה של מחלקה זו‬ ‫לבודד בין שני ההליכים‪ ,‬כך שכשאחד מהם ישתנה לא יהיה צורך בשינוי בשני‪.‬‬ ‫מחלקה זו מוגדרת ב‪ CatsDoc-‬ומכוון שמצביע ל‪ CatsDoc-‬מועבר לשני ההליכים‬ ‫שניהם מקבלים גישה לאובייקט מסוג ‪.PhantomMessanger‬‬ ‫כאשר ‪ Trial‬צירך להפעיל את הפאנטום הוא קורא לפונקציה מתאימה ב‪-‬‬ ‫‪ PhantomMessanger‬ומעביר אליה את כל הפרמטרים הנחוצים כארגומנטים‪.‬‬ ‫‪ PhantomMessanger‬שומר את הפרמטרים במשתנים הפנימיים שלו (‪data‬‬ ‫‪ )members‬ומקפיץ אירוע (‪ .)event‬ההליך של פאנטום מקשיב כל הזמן לאירועים‬ ‫ולכן קולט את האירוע וניגש למשתנים של ‪ PhantomMessanger‬כדי לקבל את‬ ‫הפרמטרים המתאימים‪.‬‬

class PhantomMessenger { public: PhantomMessenger(); virtual ~PhantomMessenger(); void MoveToPoint(double x, double y, double z, double force, double time); void RunAwayToPoint(double x, double y, double z, double force, double time); void SetSurface(double x, double y, double z, double stiff, double time); void StopMoving(); void SignalPhFinishedTask(); void SignalEventOccured(); bool CheckArea(double x,double y, double z, double r); bool CheckArea(hduVector3Dd v, double r); void SetReward(double t_before_reward, double t_reward); void SetPhToDoEventStatus(DWORD ev); DWORD GetPhToDoEventStatus(); //Events which signal the phantom to do something HANDLE ph_todo_events[NUM_OF_PHANTOM_TODO_EVENTS]; CEvent ev_todo_surface; CEvent ev_todo_move; CEvent ev_todo_runaway; CEvent ev_todo_reward; HANDLE ph_stop_event; CEvent ev_todo_stop_move; HANDLE ph_finished_event; CEvent ev_finished_move; HANDLE ph_event_status; CEvent ev_event_status; //Phantom Parameters hduVector3Dd m_vPointToMoveTo; double m_dMoveForce; hduVector3Dd m_vSurfacePoint; double m_dSurfaceStiffness; hduVector3Dd m_vFeedCenter; double m_dFeedRadius; hduVector3Dd m_vPhCurLocation; //Timing Parameters double m_dTimeToReachTarget; //time given to Cat to grab the target double m_dTimeMoveToPosition; //time given the target to get to point double m_dTimeForReward; double m_dTimeEscape; private: DWORD dw_ph_event_status; //holds the current phantom todo event };

‫‪.1.22‬כרטיס ‪ A/D‬והמשאבה‬ ‫כאמור האות להפעלת ועצירת המשאבה מועבר למשאבה דרך כרטיס ‪.A/D‬‬ ‫המעגל שמתפקד כמתאם בין הכרטיס והמשאבה עובד כמו מפסק‪ ,‬הוא מפעיל‬ ‫את המשאבה כאשר הכרטיס מספק לו מתח של ‪ 5V‬ומפסיק אותה כאשר אין‬ ‫מתח‪ .‬למטרה הזו השתמשתי ב‪ line-‬אחד של הכרטיס ו‪.ground-‬‬ ‫בכרטיס ‪ A/D‬כל ‪ line‬יכול לקבל ערך ‪ )on( 1‬או ‪ .)off( 0‬כאשר הוא במצב ‪on‬‬ ‫מסופק דרכו מתח של ‪.5V‬‬ ‫האימפלמנטציה של התקשורת עם הכרטיס מוגדרת במחלקה ‪.DIO‬‬ ‫‪class DIO‬‬ ‫{‬ ‫‪public:‬‬ ‫;)(‪DIO‬‬ ‫;)(‪virtual ~DIO‬‬ ‫‪void setLine(int line, int value); //set the value of a line‬‬ ‫‪int getLine(int line); //get the value of a line‬‬ ‫‪private:‬‬ ‫‪int32‬‬ ‫;‪error‬‬ ‫;‪TaskHandle taskHandle‬‬ ‫‪uInt8‬‬ ‫;]‪data[8‬‬ ‫‪char‬‬ ‫;]‪errBuff[2048‬‬ ‫;}‬

‫אובייקט ממחלקה זו מסוגל לרשום או לקרא ערך מערוץ אחד של הכרטיס‪.‬‬ ‫בגרסאות הבאות כרטיס ‪ A/D‬יאסוף בנוסף מידע מה‪ Force Plates-‬ויתקשר עם‬ ‫המערכת של ‪ Alpha-Omega‬ולכן יהיה צורך להוסיף יכולות נוספות למחלקה זו‪,‬‬ ‫כגון באפר‪.‬‬ ‫‪.1.23‬צלילים‬ ‫התוכנה נותנת אפשרות להשמיעה קבצי ‪ *wav.‬כדי לאפשר לתת אותות קוליים (‬ ‫‪ )audio cues‬לביצוע משימה לחתול‪.‬‬ ‫הגדרות ההשמעה נמצאות במחלקה ‪.Sound‬‬ ‫מחלקה זו כוללת פונקציה אחת בלבד‪ ,)play(int iSound ,‬אשר נקראת כאשר יש‬ ‫צורך בהשמעה של צליל‪ .‬הפרמטר יכול לקבל ערך מ‪ 1-‬עד ‪( 8‬עם אופציה‬ ‫להרחבה) וכך ניתן לבחור בין ‪ 8‬צלילים שונים‪.‬‬ ‫אובייקט מסוג ‪ Sound‬מוגדר במחלקה ‪ CatsDoc‬ולכן הוא נגיש לכל ההליכים‪.‬‬ ‫‪class Sound‬‬ ‫}‬ ‫‪public:‬‬ ‫;)(‪Sound‬‬ ‫;)(‪virtual ~Sound‬‬ ‫;)‪void Play(int iSound‬‬ ‫;}‬

‫‪.4‬פרק ‪ – 5‬תוצאות‬

‫‪.5‬פרק ‪ – 6‬סיכום ומסקנות‬

Related Documents

Final1 5
August 2019 57
Examr Final1
May 2020 29
Oratoria Final1
May 2020 28
Membership Final1
December 2019 37
Daewoo Final1
November 2019 46
Pmv Final1
June 2020 8

More Documents from ""

Al.lapusneanu.docx
November 2019 28
Muschi Pisica.pdf
December 2019 33
May 2020 47
Document.docx
November 2019 12
Bed-exercises-ml4816.pdf
December 2019 26