رابط الرسالة#
مقدمة#
تتيح فئة message_link لروبوتين من نوع EXP Brains التواصل عبر إرسال رسائل نصية قصيرة مع بيانات صغيرة اختيارية. وهي مصممة لتنسيق الروبوتات فيما بينها، مثل بدء الإجراءات الروتينية، ومشاركة نتائج المستشعرات، أو تحفيز سلوكيات معينة على روبوت آخر.
كل استخدام للأمر send يُضيف رسالة إلى قائمة انتظار وحدة المعالجة المنطقية المرتبطة، وتُقرأ هذه القائمة وفقًا لأسلوب “الوارد أولًا يُخرج أولًا” (FIFO). إذا أُرسلت عدة رسائل قبل أن تستخدم وحدة المعالجة المنطقية الأخرى الأمر receive، فسيتم تخزينها وإعادتها واحدة تلو الأخرى بالترتيب الذي أُرسلت به. نظرًا لإمكانية تراكم الرسائل في قائمة الانتظار، فإن إرسال الحالة نفسها بشكل متكرر في كل دورة قد يُؤدي إلى تراكم الرسائل؛ لذا، بالنسبة للمنطق الحساس للوقت، يُنصح بالإرسال فقط عند تغيير القيم.
هام: يجب أن يقوم كلا الروبوتين بتشغيل مشاريع تستخدم message_link في نفس الوقت، وإلا فلن يتم إرسال/استقبال أي رسائل.
مُنشئات الفئات#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
مُدمِّر الفئة#
يقوم بتدمير الكائن message_link وتحرير الموارد المرتبطة به.
virtual ~message_link();
حدود#
المعلمة |
يكتب |
وصف |
|---|---|---|
|
|
المنفذ الذكي الذي يتصل به راديو V5 أو الكابل الذكي، مكتوبًا على النحو التالي: |
|
|
اسم رابط الرسالة. |
|
|
نوع الرابط، إما
|
|
|
ما إذا كان كائن message_link متصلاً سلكياً.
|
مثال#
كود للروبوت 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredكود للروبوت 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
الدوال الأعضاء#
تتضمن فئة message_link الدوال الأعضاء التالية:
isLinked— تُرجع ما إذا كان هذا الدماغ متصلاً بشكل فعال بالدماغ المقترن به.send— يرسل رسالة إلى الدماغ المقترن.receive— ينتظر ويعيد الرسالة الواردة التالية.received— يسجل دالة ليتم استدعاؤها كلما تم استلام رسالة جديدة.
قبل استدعاء أي من الدوال الأعضاء في message_link message_link يجب إنشاء مثيل message_link ، كما هو موضح أدناه:
كود للروبوت 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredكود للروبوت 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
isLinked تُرجع طريقة ما إذا كانت وحدات EXP Brains الموجودة على MessageLink مقترنة ببعضها البعض.
bool isLinked();
لا تحتوي هذه الدالة على أي معلمات.
Return Valuesتُرجع هذه الدالة قيمة منطقية (boolean).
true- تم إقران دماغي EXP ويتواصلان عبر هذا الرابط.false– لم يتم إقران دماغي EXP على هذا الرابط.
من الممارسات الجيدة التحقق دائمًا من ربط EXP Brains في بداية المشروع قبل تشغيل أي كود إضافي.
Examplesكود للروبوت 1
// Tell the other robot when the screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); // Continuously send if the screen is being pressed while (true){ if (Brain.Screen.pressing()){ link.send("pressed"); } else { link.send("released"); } wait(0.05, seconds); }كود للروبوت 2
// Display if the other robot's screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } // Continuously check if Robot 1 has sent "pressed" while (true){ Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); char msg[32] = {0}; // buffer for incoming message int32_t n = link.receive(msg, sizeof(msg), 100); // wait up to 100ms if (n > 0 && strcmp(msg, "pressed") == 0) { Brain.Screen.newLine(); Brain.Screen.print("Manager is being pressed!"); } wait(0.05, seconds); }
send#
يرسل رسالة عبر اتصال الرابط.
Available FunctionsParameters1 — يرسل سلسلة رسائل.
int32_t send( const char *message );2 — يرسل سلسلة رسائل تحتوي على
double.int32_t send( const char *message, double value );3 — يرسل سلسلة رسالة تحتوي على
int32_tوdouble.int32_t send( const char *message, int32_t index, double value );
المعلمة |
يكتب |
وصف |
|---|---|---|
|
|
الرسالة التي يجب إرسالها إلى الدماغ الآخر المرتبط بـ EXP. |
|
|
عدد صحيح لإرساله إلى وحدة EXP Brain الأخرى المرتبطة. |
|
|
عدد عشري مزدوج لإرساله إلى وحدة المعالجة المنطقية الأخرى المرتبطة. يتم تنسيق الأعداد العشرية المزدوجة إلى 4 منازل عشرية؛ إذا تم توفير عدد أقل من المنازل العشرية، تتم إضافة أصفار لاحقة حتى يتم عرض 4 منازل عشرية. |
هذه الدالة لا تُرجع أي قيم.
Notesإذا تم إرسال الرسالة message فقط، فإن جهاز EXP Brain المرتبط الآخر يتلقى تلك الرسالة بالضبط.
إذا تم تضمين القيمة value (والقيمة index إذا تم توفيرها)، فإن الدماغ المستقبل يتلقى رسالة مشفرة واحدة تجمع جميع الحقول بهذا الترتيب: .message_index_value
باستخدام link.send(“string”, 1, 2.55) كـ .string_1_2.5500.
كود للروبوت 1
// Tell the other robot when the screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); // Continuously send if the screen is being pressed while (true){ if (Brain.Screen.pressing()){ link.send("pressed"); } else { link.send("released"); } wait(0.05, seconds); }كود للروبوت 2
// Display if the other robot's screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } // Continuously check if Robot 1 has sent "pressed" while (true){ Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); char msg[32] = {0}; // buffer for incoming message int32_t n = link.receive(msg, sizeof(msg), 100); // wait up to 100ms if (n > 0 && strcmp(msg, "pressed") == 0) { Brain.Screen.newLine(); Brain.Screen.print("Manager is being pressed!"); } wait(0.05, seconds); }
receive#
يستقبل رسالة من اتصال الرابط.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
المعلمة |
يكتب |
وصف |
|---|---|---|
|
|
المخزن المؤقت لتخزين الرسالة المستلمة. |
|
|
طول المخزن المؤقت. |
|
|
How long in milliseconds |
تقوم هذه الدالة بإرجاع عدد البايتات المستلمة.
Notesيُعيد
receiveالرسالة التالية المُدرجة في قائمة الانتظار من وحدة المعالجة الأخرى المرتبطة. تُقرأ الرسائل بترتيب FIFO (الأقدم غير المقروءة أولاً). إذا كانت قائمة الانتظار فارغة عند استدعاءreceive، فإنه ينتظر حتى انتهاءtimeoutلرسالة جديدة. إذا لم تصل أي رسالة خلال هذه الفترة، يُعيدreceive0، وتبقى أي رسالة مُرسلة بعد ذلك في قائمة الانتظار ليتم قراءتها في المرة التالية التي يُستخدم فيها الأمرreceive.إذا أرسل الدماغ المتصل الآخر سلسلة
stringوreceiveويعيدان تلك السلسلة بالضبط.إذا أرسل جهاز EXP Brain المرتبط الآخر عددًا صحيحًا و/أو عددًا عشريًا، فإن
receive، ويعيد سلسلة مشفرة واحدة تجمع جميع الحقول بهذا الترتيب:.string_integer_floatعلى سبيل المثال، إذا استخدم برنامج EXP Brain المرتبط الآخر
link.send(“string”, 1, 2.55)link.receive()يُعيد سلسلة مُشفّرة مثل.string_1_2.5500يمكنك تقسيم هذه السلسلة المُشفّرة (انظر الأمثلة أدناه) لاستخراج اسم الرسالة، والقيم الصحيحة، والقيم العشرية.إذا كنت تفضل تجنب التقسيم/التحليل اليدوي، فاستخدم
receivedلتسجيل معالج لاسم رسالة معين؛ يتلقى المعالج القيم المرسلة كوسائط.
باستخدام link.send(“string”, 1, 2.55) كـ .string_1_2.5500.
كود للروبوت 1
// Tell the other robot when the screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); // Continuously send if the screen is being pressed while (true){ if (Brain.Screen.pressing()){ link.send("pressed"); } else { link.send("released"); } wait(0.05, seconds); }كود للروبوت 2
// Display if the other robot's screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } // Continuously check if Robot 1 has sent "pressed" while (true){ Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); char msg[32] = {0}; // buffer for incoming message int32_t n = link.receive(msg, sizeof(msg), 100); // wait up to 100ms if (n > 0 && strcmp(msg, "pressed") == 0) { Brain.Screen.newLine(); Brain.Screen.print("Manager is being pressed!"); } wait(0.05, seconds); }
received#
يسجل وظيفة ليتم استدعاؤها كلما تلقى برنامج EXP Brain رسالة مرسلة.
Available FunctionsParameters1 يسجل رد نداء لجميع الرسائل المستلمة (الرسالة + القيمة).
void received( void (* callback)(const char *, const char *, double) );2 يسجل رد نداء لجميع الرسائل المستلمة (الرسالة + الفهرس + القيمة).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 يسجل رد اتصال لرسالة محددة (الرسالة + القيمة).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 يسجل رد نداء لرسالة محددة (الرسالة + الفهرس + القيمة).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
المعلمة |
يكتب |
وصف |
|---|---|---|
|
|
اسم الرسالة المراد الاستماع إليها. في حال عدم تحديده، يتم تشغيل دالة الاستدعاء لجميع الرسائل المستلمة. |
|
مؤشر الدالة |
دالة يتم تنفيذها عند استلام رسالة. |
هذه الدالة لا تُرجع أي قيم.
Callback Signature1 يستقبل اسم المرسل واسم الرسالة والقيمة.
void callback(const char *, const char *, double)2 يستقبل اسم المرسل، واسم الرسالة، والفهرس، والقيمة.
void callback(const char *, const char *, int32_t, double)
يكتب |
وصف |
|---|---|
1st |
اسم رابط المرسل. |
2nd |
اسم الرسالة المستلمة. |
|
الفهرس المرتبط بالرسالة. |
|
القيمة المرتبطة بالرسالة. |
كود للروبوت 1
// Send whether screen is pressed on left or right void screen_pressed() { if (Brain.Screen.xPosition() < 240) { link.send("left"); } else { link.send("right"); } } int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Create the link message_link link(PORT1, "LeftRightLink", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); Brain.Screen.pressed(screen_pressed); while (true) { wait(10, msec); } }كود للروبوت 2
// Create variable to track where screen is pressed int lastPress = 0; // Update the variable whenever a new message is received void message_received(const char* message, const char* linkname, double timestamp) { if (strcmp(message, "left") == 0) lastPress = 1; if (strcmp(message, "right") == 0) lastPress = 2; } int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Create the link message_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } link.received(message_received); // Display if Robot 1's screen was pressed on the left or right while (true) { Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); if (lastPress == 1) { Brain.Screen.print("Manager pressed LEFT"); } else if (lastPress == 2) { Brain.Screen.print("Manager pressed RIGHT"); } else { Brain.Screen.print("Waiting..."); } wait(0.1, seconds); } }