메시지 링크#
소개#
message_link 클래스는 두 EXP Brain 로봇이 짧은 문자열 메시지와 선택적으로 소량의 데이터를 주고받으며 통신할 수 있도록 합니다. 이 클래스는 로봇 간 조정, 예를 들어 루틴 시작, 센서 결과 공유 또는 다른 로봇의 동작 트리거 등에 사용하도록 설계되었습니다.
send을 사용할 때마다 연결된 EXP Brain의 큐에 메시지가 추가되며, 큐는 선입선출(FIFO) 방식으로 읽힙니다. 다른 EXP Brain이 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— 이 Brain이 쌍을 이루는 Brain에 활발하게 연결되어 있는지 여부를 반환합니다.send— 쌍을 이룬 Brain에 메시지를 보냅니다.receive— 다음 수신 메시지를 기다리고 반환합니다.received— 새 메시지가 수신될 때마다 호출될 함수를 등록합니다.
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 메서드는 MessageLink의 EXP Brain이 서로 쌍을 이루는지 여부를 반환합니다.
bool isLinked();
이 함수는 매개변수가 없습니다.
Return Values이 함수는 부울 값을 반환합니다.
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 브레인으로 보낼 정수입니다. |
|
|
연결된 다른 EXP 브레인으로 보낼 double형 값입니다. double형 값은 소수점 4자리까지 표시되어야 하며, 4자리보다 적은 자릿수를 입력하면 4자리가 될 때까지 끝에 0이 추가됩니다. |
이 함수는 값을 반환하지 않습니다.
NotesIf only message is sent, the other linked EXP Brain receives that exact message.
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 );
매개변수 |
유형 |
설명 |
|---|---|---|
|
|
수신된 메시지를 저장하는 버퍼. |
|
|
버퍼의 길이. |
|
|
|
이 함수는 수신된 바이트 수를 반환합니다.
Notesreceive연결된 다른 EXP Brain에서 대기 중인 다음 메시지를 반환합니다. 메시지는 FIFO 순서(가장 오래된 미읽은 메시지부터)로 읽습니다.receive호출될 때 큐가 비어 있으면 지정된timeout까지 새 메시지를 기다립니다. 해당 시간 내에 메시지가 도착하지 않으면receive은0을 반환하고, 이후에 전송된 메시지는 다음에receive사용될 때 읽히도록 큐에 남아 있습니다.만약 다른 연결된 EXP Brain이
string만 보냈다면,receive수신하고 정확히 그 문자열을 반환합니다.다른 연결된 EXP Brain이 정수 및/또는 부동 소수점을 전송한 경우,
receive수신하고 모든 필드를 다음 순서로 결합한 단일 인코딩된 문자열을 반환합니다:.string_integer_floatFor example, if the other linked EXP Brain uses
link.send(“string”, 1, 2.55), then usinglink.receive()returns an encoded string such as.string_1_2.5500. You can split this encoded string (see the examples below) to extract the message name, integer, and float values.수동 분할/구문 분석을 피하려면
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 브레인이 전송된 메시지를 수신할 때마다 호출될 함수를 등록합니다.
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); } }