Closed ghost closed 8 years ago
Conversions are not a good place to calculate checksums for a few reasons. Here is how COSMOS builds up commands:
The above process is actually currently happening twice, once when checking if the command is hazardous and again to build the command to actually send. (That is why you saw the conversion run 4 times). I should optimize that to only happen once. Thanks for that insight!
When calculating checksums, you need it to be done last, after everything else has already been written to the command. The process above does not guarantee that because parameters are written in the order they are specified. You could have an operational constraint to always specify the checksum field last, but that would be error prone. Also, if you did not explicitly set the checksum to 0 as you did, the conversion would have only run once during the set default values phase, and you wouldn't get the correct checksum.
Anyways, the correct solution is to set the checksum in a customized interface class. You need to subclass whatever interface you are using, override the write method to set the checksum, and then actually send the packet. Something like this:
# my_udp_interface.rb placed in your targets lib folder
# Then switch out using udp_interface.rb to my_udp_interface.rb in cmd_tlm_server.txt
require 'cosmos/interfaces/udp_interface'
module Cosmos
class MyUdpInterface < UdpInterface
def write(packet)
data = packet.buffer
checksum = # Add code here based off of using data
packet.write('CHECKSUM', checksum)
super(packet)
end
end # class
end # module
Thanks for the fast response, That makes perfect sense.
I actually wrote a blog post detailing this kind of thing: http://cosmosrb.com/news/2016/08/04/custom-cosmos_interface/
Write conversions on command parameters are tricky. They work perfectly on individual items, but across items you have to think about the timing.
I created a WRITE_CONVERSION function to compute a command checksum to put in the secondary header. Looking at the log, when I press "send" for the command, the function seems to get called 4 times. With the first and third call returning the correct value, the 2nd and 4th returning 0.
I'm new to ruby, so it is probably a newbie mistake.
Here is my function:
And the log when the command is sent:
The command definition:
Thanks