๐[BUG] - Pros::Link Issues
ifndef-define opened this issue ยท 6 comments
Describe the bug
When experimenting with the vexLink system in pros, I came across two issues:
- When starting a program with a pros::Link device initialized and with two radios connected to the brain, the radio designated as the link radio doesn't initialize (the radio doesn't flash red at 2hz). And when the
ov
parameter is set to true, the brain black screens and nothing works at all. However, when I start with one radio connected to the brain (ov
set to true), it initializes correctly and links with the other radio (with the red-green flashing), and then I connect the other radio back which connects to the controller without any problem. - I have not been able to send any data via pros::Link. I have tried numerous ways to send data using the
transmit
andtransmit_raw
functions and the respective receive functions to no avail. I even used the exact layout from the pros documentation (except the constructor which is incorrect on the docs) to get data to be sent but it doesn't work.
To Reproduce
For the first issue:
- Connect two radios to the brain
- Start a program with a pros::Link device constructor
- Radio does not initialize
The way I got it to work:
- Connect the link radio only
- Start a program with a pros::Link device constructor and the
ov
parameter set to true - The radio initializes and connects to another brain with the same initialization as a receiver
- Connect the second radio back to the brain
Expected behavior
Two radios connected to the robot, one designated as a pros::Link radio should initialize at program start, connect and send data to the other brain.
Desktop (please complete the following information):
- OS: Windows 11 Home
- VSC: v0.6.0
- Kernal Version 3.8.0
Addon Feature
I do not know if this is possible, but is there a way to switch the initializations of the pros::Link devices? The link at the moment only allows sending data in one direction, but in reality it would be better to be able to send in both by switching the job of transmitter and receiver.
Also would like to add the error values and the code snipet;
I used the exact values from the docs. The method is constantly returning EINVAL
(Invalid Argument).
Code:
char* result;
char* expected = "Hello!";
data = test_trans.receive((void*)result, sizeof(*expected) * sizeof(expected));
receiveErrorVal = errno;
lcd::print(6, "Data: %d", data);
lcd::print(7, "Error: %d", receiveErrorVal);
Output:
Data; INT32_MAX
Error; 22
The link docs need some changes in the meantime here's an example of receiving data currently
// The expected message. Only the size matters.
char expected[] = "Hello!";
// size_t is an unsigned int for things like array size.
size_t msgSize = sizeof(expected);
// Where the received message will be stored
char data[msgSize]; // Array with the same size as the expected message. "Hello!" has 7 characters so 7 bytes
// The first parameter is where to store received data (address) second param is the size of the received data
test_trans.receive(&data, msgSize);
lcd::print(6, "Data: %d", data);
This should work don't have access to testing right now so let me know if there are any problems
size_t: https://pvs-studio.com/en/blog/terms/0044/
Fixed typo.
I do not know if this is possible, but is there a way to switch the initializations of the pros::Link devices? The link at the moment only allows sending data in one direction, but in reality it would be better to be able to send in both by switching the job of transmitter and receiver.
This should already be possible. Both receivers and transmitters can receive and transmit data. For example you can have a program where a transmitter transmits a value to a receiver where the value is modified and sent back to the transmitter to be displayed.
pros::Link transmitter(1, "RobotID", pros::E_LINK_TRANSMITTER, true);
transmitter.transmit(&data, size);
transmitter.receive(&modData, size);
// Display modified data
And
pros::Link receiver(1, "RobotID", pros::E_LINK_RECIEVER, true);
receiver.receive(&data, size);
// Mod data
receiver.transmit(&modData, size);
The way I got it to work:
- Connect the link radio only
- Start a program with a pros::Link device constructor and the
ov
parameter set to true- The radio initializes and connects to another brain with the same initialization as a receiver
- Connect the second radio back to the brain
Did some testing and we're looking into this hoping to roll out a fix soon along with a docs update. This method is a temporary solution if you're having problems with dual radios.
Thank you so much for the response! Good to hear that most of the problems were just outdated docs and nothing major code-wise. Ill keep you posted on anything else that I find.
The way I got it to work:
- Connect the link radio only
- Start a program with a pros::Link device constructor and the
ov
parameter set to true- The radio initializes and connects to another brain with the same initialization as a receiver
- Connect the second radio back to the brain
Did some testing and we're looking into this hoping to roll out a fix soon along with a docs update. This method is a temporary solution if you're having problems with dual radios.
Good news, I found the problem with dual radios. When dealing with radios, the brain prioritizes the radio on a higher # port to be the controller radio and disables the other radios that are connected. When I initially posted this issue, I had it so the link radio was on a port number that was lower than the designated controller radio (ex. link lets say is port 5, and the radio is port 21). Since the link radio is disabled (by the flashing red light at the cable connection) the brain doesn't realize the radio existed at the initialization of the link, thus the problem. The solution is to have the link radio on a higher port number than the controller radio (ex. link on 21 and radio on 5). This works since parameter ov
when set to true
will override the current radio (configured as a controller radio) long enough for the brain to initialize the second radio (the designated link radio) as another controller radio before the first one turns back as a link radio. I believe this is a firmware-based thing, so a docs note should be good for help with explaining dual radio connections.
Edit: I would also like to add the fact that when I call the link constructor inside a constructor for a class that I created, the brain black screens and nothing initializes. All ports flash red and there is no response from the program.
LinkHelper::LinkHelper()
{
// This doesn't work. Not even the lcd initializes
pros::Link linkTransmit(15, "link_key", E_LINK_TRANSMITTER, true);
};