-
|
We have a running demonstration of interfacing Fprime with YAMCS using TlmPacketizer, but we need to upgrade it to TlmChan. One of the ways we have found to make it happen requires the use of TCP both ways, but YAMCS requires TM and TC to go through separate ports which the Drv.TcpServer component is not designed for. What is the recommended way to use TCP for both TM and TC using separate ports? Every attempt I have made so far fails because of unconnected ports, and it feels wrong to just create dummy components which go nowhere just to go around this problem. Many thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
|
You could create some ground-side script that will host two ports and proxy to the Fprime TcpServer. Probably best to use the out-of-the box components in F'. |
Beta Was this translation helpful? Give feedback.
-
|
Ground side script that splits out the stream as @Kronos3 said would likely be an easy solution. If you'd rather avoid that, you can create 2 Something like that: instance uplinkComDriver: Drv.TcpClient base id 0x10014000
instance downlinkComDriver: Drv.TcpClient base id 0x10015000
[...]
connections Communications {
# ComDriver buffer allocations
uplinkComDriver.allocate -> ComCcsds.commsBufferManager.bufferGetCallee
uplinkComDriver.deallocate -> ComCcsds.commsBufferManager.bufferSendIn
# ComDriver <-> ComStub (Uplink)
uplinkComDriver.$recv -> ComCcsds.comStub.drvReceiveIn
ComCcsds.comStub.drvReceiveReturnOut -> uplinkComDriver.recvReturnIn
# ComStub <-> ComDriver (Downlink)
ComCcsds.comStub.drvSendOut -> downlinkComDriver.$send
downlinkComDriver.ready -> ComCcsds.comStub.drvConnected
}Then make sure to set them up properly # Topology.cpp
if (state.hostname != nullptr && state.port != 0) {
uplinkComDriver.configure(state.hostname, state.port + 1); // configure ports here...
downlinkComDriver.configure(state.hostname, state.port);
}
[...]
if (state.hostname != nullptr && state.port != 0) {
Os::TaskString name("ReceiveTask");
// Uplink is configured for receive so a socket task is started
uplinkComDriver.start(name, COMM_PRIORITY, Default::STACK_SIZE);
downlinkComDriver.start(name, COMM_PRIORITY, Default::STACK_SIZE);
}
[...]
// Other task clean-up.
uplinkComDriver.stop();
(void)uplinkComDriver.join();
downlinkComDriver.stop();
(void)downlinkComDriver.join();
If you're getting asserts that I was playing on the HelloWorld deployment and added a sink to the HelloWorld component # HelloWorld.fpp
guarded input port recv_sink: Drv.ByteStreamDatavoid HelloWorld ::recv_sink_handler(FwIndexType portNum, Fw::Buffer& buffer, const Drv::ByteStreamStatus& status) {
return;
}# topology.fpp
downlinkComDriver.$recv -> helloWorld.recv_sinkAnd that worked! Depending on the GDS port I specify, I either get only uplink or only downlink 🎉 ( |
Beta Was this translation helpful? Give feedback.
-
|
Thanks @thomas-bc and @Kronos3 for the quick answers, I'll give it a shot. I was planning on making that interface public after it is ready anyway, but it makes even more sense to collaborate sooner now that it sounds like there is interest on your side. If you don't mind looking at demonstrations which are exploratory before they are properly reviewed (we have a support contract with SpaceApplications which I'm yet to use on that review for example), I could grant you access to the private demo. The majority of the clunkiness of our current solution comes from the fact that the fprime-gds API doesn't give us the necessary information for the generation of the YAMCS mission database (fields types and sizes etc.) and we have to parse the deployment dictionary ourselves to extract it out. The two separate ports are the other hurdle, but other than that, I believe it's more time consuming to make than complicated in itself. YAMCS is very powerful, we have been using it for years operationally. Definitely worth making Fprime compatible with it, especially now that CCSDS support has been added. We are not using that (the Fprime protocol is simple enough), but it would probably be cleaner. |
Beta Was this translation helpful? Give feedback.
Ground side script that splits out the stream as @Kronos3 said would likely be an easy solution.
If you'd rather avoid that, you can create 2
TcpClientcomponents (or servers, whichever), one for downlink and one for uplink. Then hook the uplink one to the uplink part of ComStub, and the downlink one to downlink of ComStub.Something like that: