From 5d34dce9733e8bb391de2361603c5a9418a4512b Mon Sep 17 00:00:00 2001 From: Ian Lowe Date: Thu, 28 May 2026 12:15:40 -0700 Subject: [PATCH 1/6] adding hardware watchdog bypass and take incharge --- blast_config/command_list.c | 4 ++++ blast_config/include/command_list.h | 4 ++++ mcp/commanding/commands.c | 13 +++++++++++++ mcp/communications/bi0.c | 6 +++++- mcp/include/command_struct.h | 2 ++ 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/blast_config/command_list.c b/blast_config/command_list.c index e0cdfd853..114abc767 100644 --- a/blast_config/command_list.c +++ b/blast_config/command_list.c @@ -254,6 +254,10 @@ struct scom scommands[xyzzy + 1] = { /* MISC */ + // HW watchdog and in charge + {COMMAND(disallow_hw_wd), "Setting the HW watchdog to be ignored", GR_MISC | CONFIRM}, + {COMMAND(allow_hw_wd), "Setting the HW watchdog to be listened to", GR_MISC | CONFIRM}, + {COMMAND(take_incharge), "Setting InCharge to 1 and taking control", GR_MISC | CONFIRM}, // Video transmitters {COMMAND(vtx_xsc0), "Setting video transmitter to XSC0", GR_XSC_MODE | GR_TELEM}, {COMMAND(vtx_xsc1), "Setting video transmitter to XSC1", GR_XSC_MODE | GR_TELEM}, diff --git a/blast_config/include/command_list.h b/blast_config/include/command_list.h index 1408608fc..de2174585 100644 --- a/blast_config/include/command_list.h +++ b/blast_config/include/command_list.h @@ -219,6 +219,10 @@ enum singleCommand { sc2_trigger_off, /* MISC */ + // HW watchdog + disallow_hw_wd, + allow_hw_wd, + take_incharge, // Video transmitters vtx_xsc0, vtx_xsc1, diff --git a/mcp/commanding/commands.c b/mcp/commanding/commands.c index 0dd5865f0..3ba8101d3 100644 --- a/mcp/commanding/commands.c +++ b/mcp/commanding/commands.c @@ -868,6 +868,16 @@ void SingleCommand(enum singleCommand command, int scheduled) break; /* MISC */ + // HW WD and incharge + case disallow_hw_wd: + CommandData.bypass_HW_WD = 1; + break; + case allow_hw_wd: + CommandData.bypass_HW_WD = 0; + break; + case take_incharge: + InCharge = 1; + break; // Video transmitters case vtx_xsc0: CommandData.vtx_sel[0] = VTX_XSC0; @@ -2684,6 +2694,9 @@ void InitCommandData() is_valid = (prev_crc == crc32_le(0, (uint8_t*)&CommandData, sizeof(CommandData))); /** this overrides prev_status **/ + // HW WD BYPASS MUST BE 0 ON STARTUP + CommandData.bypass_HW_WD = 0; + CommandData.sc_bools.sc1_command_bool = 1; CommandData.sc_bools.sc2_command_bool = 1; CommandData.sc_bools.sc1_image_bool = 1; diff --git a/mcp/communications/bi0.c b/mcp/communications/bi0.c index 532804ddf..989aa48ff 100644 --- a/mcp/communications/bi0.c +++ b/mcp/communications/bi0.c @@ -241,7 +241,11 @@ static LIBUSB_CALL void biphase_write_cb(struct libusb_transfer * biphase_write_ if (reader_done) { // set in charge based on latest read in_charge_from_wd = (watchdog_read_buffer[2] & 0x40) >> 6; // get pin 6 state - set_incharge(in_charge_from_wd); + // Ian 5/28/2026 + // adding a conditional to ignore the WD card in charge if we decide to bypass it via command + if (CommandData.bypass_HW_WD == 0) { + set_incharge(in_charge_from_wd); + } // blast_info("in charge from watchdog reads %d", in_charge_from_wd); // toggle pin 7 for the watchdog ping and write new state diff --git a/mcp/include/command_struct.h b/mcp/include/command_struct.h index 7b002060e..26ae27f1f 100644 --- a/mcp/include/command_struct.h +++ b/mcp/include/command_struct.h @@ -428,6 +428,8 @@ typedef struct { * */ struct CommandDataStruct { + int bypass_HW_WD; + uint16_t command_count; uint16_t last_command; From 6e3ab68b39e0ed097950cf3e39358d33bdee5640 Mon Sep 17 00:00:00 2001 From: Ian Lowe Date: Thu, 28 May 2026 12:30:54 -0700 Subject: [PATCH 2/6] changed comment wording --- mcp/commanding/commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcp/commanding/commands.c b/mcp/commanding/commands.c index 3ba8101d3..ae2be6d5f 100644 --- a/mcp/commanding/commands.c +++ b/mcp/commanding/commands.c @@ -868,7 +868,7 @@ void SingleCommand(enum singleCommand command, int scheduled) break; /* MISC */ - // HW WD and incharge + // HW watchdog and incharge case disallow_hw_wd: CommandData.bypass_HW_WD = 1; break; From 63d5ebac05a5ee6e4318ee8fe5e78a6cc656d313 Mon Sep 17 00:00:00 2001 From: Ian Lowe Date: Mon, 8 Jun 2026 10:07:28 -0700 Subject: [PATCH 3/6] Adding UDP streams for pointing data to ACOMP computer and commanding for ACOMP to save data. Additionally added commands to MCP to control the flow of commanding to the ACOMP, along with all requisite command data and definitions. These have been tested to ensure the packets come out in correct form to a fake analysis computer, but will need full link testing onces we have the RFSOC and FCs on the same network to ensure everything is lined up properly in the saved files --- blast_config/command_list.c | 9 + blast_config/include/command_list.h | 5 + mcp/commanding/commands.c | 25 +++ mcp/communications/CMakeLists.txt | 2 + mcp/communications/analysis_comp_sharing.c | 158 ++++++++++++++++++ mcp/communications/analysis_comp_trigger.c | 120 +++++++++++++ .../include/analysis_comp_sharing.h | 38 +++++ .../include/analysis_comp_trigger.h | 31 ++++ mcp/include/command_struct.h | 8 + mcp/mcp.c | 14 ++ 10 files changed, 410 insertions(+) create mode 100644 mcp/communications/analysis_comp_sharing.c create mode 100644 mcp/communications/analysis_comp_trigger.c create mode 100644 mcp/communications/include/analysis_comp_sharing.h create mode 100644 mcp/communications/include/analysis_comp_trigger.h diff --git a/blast_config/command_list.c b/blast_config/command_list.c index 114abc767..e5bb48800 100644 --- a/blast_config/command_list.c +++ b/blast_config/command_list.c @@ -254,6 +254,9 @@ struct scom scommands[xyzzy + 1] = { /* MISC */ + // acomp + {COMMAND(acomp_start_saving), "Telling ACOMP to start saving data", GR_MISC}, + {COMMAND(acomp_stop_saving), "Telling ACOMP to stop saving data", GR_MISC}, // HW watchdog and in charge {COMMAND(disallow_hw_wd), "Setting the HW watchdog to be ignored", GR_MISC | CONFIRM}, {COMMAND(allow_hw_wd), "Setting the HW watchdog to be listened to", GR_MISC | CONFIRM}, @@ -1550,6 +1553,12 @@ struct mcom mcommands[plugh + 2] = { }, /* MISC */ + // ACOMP + {COMMAND(acomp_save_n_seconds), "Tell ACOMP to save N seconds of data", GR_MISC, 1, + { + {"Length of timestream", 1, 1200, 'i', "NONE"} + } + }, // XY stage {COMMAND(xy_goto), "move the X-Y translation stage to absolute position", GR_MISC, 4, { diff --git a/blast_config/include/command_list.h b/blast_config/include/command_list.h index de2174585..e9f518f6f 100644 --- a/blast_config/include/command_list.h +++ b/blast_config/include/command_list.h @@ -219,6 +219,9 @@ enum singleCommand { sc2_trigger_off, /* MISC */ + // acomp + acomp_start_saving, + acomp_stop_saving, // HW watchdog disallow_hw_wd, allow_hw_wd, @@ -465,6 +468,8 @@ enum multiCommand { xsc_filter_matching, /* MISC */ + // acomp + acomp_save_n_seconds, // XY stage xy_goto, xy_jump, diff --git a/mcp/commanding/commands.c b/mcp/commanding/commands.c index ae2be6d5f..15a62ec69 100644 --- a/mcp/commanding/commands.c +++ b/mcp/commanding/commands.c @@ -868,6 +868,19 @@ void SingleCommand(enum singleCommand command, int scheduled) break; /* MISC */ + // acomp + case acomp_start_saving: + CommandData.acomp_commands.send_trigger = 1; + CommandData.acomp_commands.trigger_value = 1; + CommandData.acomp_commands.counting = 0; + CommandData.acomp_commands.countdown = 0; + break; + case acomp_stop_saving: + CommandData.acomp_commands.send_trigger = 1; + CommandData.acomp_commands.trigger_value = 0; + CommandData.acomp_commands.counting = 0; + CommandData.acomp_commands.countdown = 0; + break; // HW watchdog and incharge case disallow_hw_wd: CommandData.bypass_HW_WD = 1; @@ -2518,6 +2531,13 @@ void MultiCommand(enum multiCommand command, double *rvalues, } /* MISC */ + // acomp + case acomp_save_n_seconds: + CommandData.acomp_commands.send_trigger = 1; + CommandData.acomp_commands.trigger_value = 1; + CommandData.acomp_commands.counting = 1; + CommandData.acomp_commands.countdown = ivalues[0]; + break; // XY stage case xy_goto: CommandData.xystage.x1 = ivalues[0]; @@ -2697,6 +2717,11 @@ void InitCommandData() // HW WD BYPASS MUST BE 0 ON STARTUP CommandData.bypass_HW_WD = 0; + CommandData.acomp_commands.countdown = 0; + CommandData.acomp_commands.send_trigger = 0; + CommandData.acomp_commands.trigger_value = 0; + CommandData.acomp_commands.counting = 0; + CommandData.sc_bools.sc1_command_bool = 1; CommandData.sc_bools.sc2_command_bool = 1; CommandData.sc_bools.sc1_image_bool = 1; diff --git a/mcp/communications/CMakeLists.txt b/mcp/communications/CMakeLists.txt index 9c2342563..02190dc3a 100644 --- a/mcp/communications/CMakeLists.txt +++ b/mcp/communications/CMakeLists.txt @@ -4,6 +4,8 @@ add_library (communications STATIC ${CMAKE_CURRENT_SOURCE_DIR}/pilot.c ${CMAKE_CURRENT_SOURCE_DIR}/highrate.c ${CMAKE_CURRENT_SOURCE_DIR}/evtm.c + ${CMAKE_CURRENT_SOURCE_DIR}/analysis_comp_sharing.c + ${CMAKE_CURRENT_SOURCE_DIR}/analysis_comp_trigger.c ) define_file_basename_for_sources(communications) diff --git a/mcp/communications/analysis_comp_sharing.c b/mcp/communications/analysis_comp_sharing.c new file mode 100644 index 000000000..4d6f8aaae --- /dev/null +++ b/mcp/communications/analysis_comp_sharing.c @@ -0,0 +1,158 @@ +/* analysis_comp_sharing.c: TIM threads and functions for sharing pointing with acomp1 + * + * This software is copyright (C) 2026 University of Arizona + * + * This file is part of the BLAST flight code licensed under the GNU + * General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "socket_utils.h" +#include "analysis_comp_sharing.h" +#include "command_struct.h" +#include "tx.h" +#include "channels_tng.h" + +int proceed_with_loop_trigger = 0; + +/** + * @brief takes a pointer to a pointing data packet, sets up channel pointers, + * and fills the packet with the most recent data from each channel + * + * @param packet the pointer to the packet that we will fill from channels + */ +void fill_packet_from_channels(pointing_data* packet) { + static channel_t *az_Addr, *el_Addr, *lat_Addr, *lon_Addr; + static channel_t *height_Addr, *time_Addr, *time_usec_Addr; + static int first_time = 1; + if (first_time) { + first_time = 0; + az_Addr = channels_find_by_name("az"); + el_Addr = channels_find_by_name("el"); + lat_Addr = channels_find_by_name("lat"); + lon_Addr = channels_find_by_name("lon"); + height_Addr = channels_find_by_name("alt"); + time_Addr = channels_find_by_name("time"); + time_usec_Addr = channels_find_by_name("time_usec"); + } + GET_SCALED_VALUE(az_Addr, packet->az); + GET_SCALED_VALUE(el_Addr, packet->el); + GET_SCALED_VALUE(lat_Addr, packet->latitude); + GET_SCALED_VALUE(lon_Addr, packet->longitude); + GET_VALUE(height_Addr, packet->height); + GET_VALUE(time_Addr, packet->time); + GET_VALUE(time_usec_Addr, packet->time_usec); +} + +/** + * @brief clears the data stored in a pointing packet to ensure old data never leaks in + * + * @param packet the pointer to the packet that we will clear + */ +void clear_packet_data(pointing_data* packet) { + memset(packet, 0, sizeof(pointing_data)); +} + +/** + * @brief triggers the acomp send loop to prepare and + * send a packet of pointing data to the acomp + * has in charge protection to ensure that only the in charge + * computer is sending the data to the acomp + * + */ +void get_acomp_shared_data_1hz(void) { + if (InCharge) { + proceed_with_loop_trigger = 1; + } +} + +// here goes the actual thread that we call +void * send_pointing_data_acomp(void* args) { + pointing_data acomp_packet; + struct socketData * socket_target = args; + int first_time = 1; + int sockfd; + struct addrinfo hints; + struct addrinfo *servinfo; + struct addrinfo *servinfoCheck; + int returnval; + int bytes_sent; + int length; + int *retval; + char message_str[40]; + char ipAddr[INET_ADDRSTRLEN]; + while (1) { + if (first_time == 1) { + first_time = 0; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; // set to AF_INET to use IPv4 + hints.ai_socktype = SOCK_DGRAM; + // fill out address info and return if it fails. + if ((returnval = getaddrinfo(socket_target->ipAddr, socket_target->port, &hints, &servinfo)) != 0) { + blast_err("getaddrinfo: %s\n", gai_strerror(returnval)); + return NULL; + } + // now we make a socket with this info + for (servinfoCheck = servinfo; servinfoCheck != NULL; servinfoCheck = servinfoCheck->ai_next) { + if ((sockfd = socket(servinfoCheck->ai_family, + servinfoCheck->ai_socktype, servinfoCheck->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + break; + } + // check to see if we made a socket + if (servinfoCheck == NULL) { + // set status to 0 (dead) if this fails + blast_err("talker: failed to create socket\n"); + return NULL; + } + // if we pass all of these checks then + // we set up the print statement vars + // need to cast the socket address to an INET still address + struct sockaddr_in *ipv = (struct sockaddr_in *)servinfo->ai_addr; + // then pass the pointer to translation and put it in a string + inet_ntop(AF_INET, &(ipv->sin_addr), ipAddr, INET_ADDRSTRLEN); + blast_info("IP target is: %s\n", ipAddr); + // now the "str" is packed with the IP address string + // first time setup of the socket is done + } + while (!proceed_with_loop_trigger) { + usleep(10000); + } + fill_packet_from_channels(&acomp_packet); + if (!strcmp(socket_target->ipAddr, ipAddr)) { + length = sizeof(acomp_packet); + printf("length of packet is %d!!!!!!!\n", length); + if ((bytes_sent = sendto(sockfd, &acomp_packet, length, 0, + servinfo->ai_addr, servinfo->ai_addrlen)) == -1) { + perror("talker: sendto"); + } + } else { + blast_err("Target destination %s differs from thread target %s.\n", socket_target->ipAddr, ipAddr); + } + proceed_with_loop_trigger = 0; + } + freeaddrinfo(servinfo); + close(sockfd); + return NULL; +}; + diff --git a/mcp/communications/analysis_comp_trigger.c b/mcp/communications/analysis_comp_trigger.c new file mode 100644 index 000000000..d3bbda935 --- /dev/null +++ b/mcp/communications/analysis_comp_trigger.c @@ -0,0 +1,120 @@ +/* analysis_comp_trigger.c: TIM threads and functions for triggering data save on acomp1 + * + * This software is copyright (C) 2026 University of Arizona + * + * This file is part of the BLAST flight code licensed under the GNU + * General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "socket_utils.h" +#include "analysis_comp_trigger.h" +#include "command_struct.h" +#include "tx.h" +#include "channels_tng.h" + +/** + * @brief function that goes in the 1hz loop to perform a delayed stop taking data countdown. + * + */ +void acomp_countdown_1hz(void) { + if (CommandData.acomp_commands.counting == 1) { + if (CommandData.acomp_commands.countdown == 0) { + CommandData.acomp_commands.send_trigger = 1; + CommandData.acomp_commands.trigger_value = 0; + } + CommandData.acomp_commands.countdown--; + } +} + + + +// here goes the actual thread that we call +void * send_data_trigger_acomp(void* args) { + struct trigger acomp_trigger; + struct socketData * socket_target = args; + int first_time = 1; + int sockfd; + struct addrinfo hints; + struct addrinfo *servinfo; + struct addrinfo *servinfoCheck; + int returnval; + int bytes_sent; + int length; + int *retval; + char message_str[40]; + char ipAddr[INET_ADDRSTRLEN]; + while (1) { + if (first_time == 1) { + first_time = 0; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; // set to AF_INET to use IPv4 + hints.ai_socktype = SOCK_DGRAM; + // fill out address info and return if it fails. + if ((returnval = getaddrinfo(socket_target->ipAddr, socket_target->port, &hints, &servinfo)) != 0) { + blast_err("getaddrinfo: %s\n", gai_strerror(returnval)); + return NULL; + } + // now we make a socket with this info + for (servinfoCheck = servinfo; servinfoCheck != NULL; servinfoCheck = servinfoCheck->ai_next) { + if ((sockfd = socket(servinfoCheck->ai_family, + servinfoCheck->ai_socktype, servinfoCheck->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + break; + } + // check to see if we made a socket + if (servinfoCheck == NULL) { + // set status to 0 (dead) if this fails + blast_err("talker: failed to create socket\n"); + return NULL; + } + // if we pass all of these checks then + // we set up the print statement vars + // need to cast the socket address to an INET still address + struct sockaddr_in *ipv = (struct sockaddr_in *)servinfo->ai_addr; + // then pass the pointer to translation and put it in a string + inet_ntop(AF_INET, &(ipv->sin_addr), ipAddr, INET_ADDRSTRLEN); + blast_info("IP target is: %s\n", ipAddr); + // now the "str" is packed with the IP address string + // first time setup of the socket is done + } + if (CommandData.acomp_commands.send_trigger == 1 && InCharge) { + acomp_trigger.take_data = CommandData.acomp_commands.trigger_value; // pull the value into the packet + CommandData.acomp_commands.send_trigger = 0; // don't try to send again + if (!strcmp(socket_target->ipAddr, ipAddr)) { + length = sizeof(acomp_trigger); + if ((bytes_sent = sendto(sockfd, &acomp_trigger, length, 0, + servinfo->ai_addr, servinfo->ai_addrlen)) == -1) { + perror("talker: sendto"); + } + } else { + blast_err("Target destination %s differs from thread target %s.\n", socket_target->ipAddr, ipAddr); + } + } else { + usleep(100000); + } + } + freeaddrinfo(servinfo); + close(sockfd); + return NULL; +}; diff --git a/mcp/communications/include/analysis_comp_sharing.h b/mcp/communications/include/analysis_comp_sharing.h new file mode 100644 index 000000000..593a0d1d7 --- /dev/null +++ b/mcp/communications/include/analysis_comp_sharing.h @@ -0,0 +1,38 @@ +/* analysis_comp_sharing.h: TIM data structures and function primals mcp to acomp 1 data link + * + * This software is copyright (C) 2026 University of Arizona + * + * This file is part of the BLAST flight code licensed under the GNU + * General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef INCLUDE_ACOMP_SHARING_H +#define INCLUDE_ACOMP_SHARING_H + +#include "mcp.h" +#define ACOMP1_IP "192.168.1.6" +#define ACOMP_POINTING_PORT "1213" + +extern int16_t InCharge; + +typedef struct pointing_data { // need to finish designing this + float az; + float el; + float latitude; + float longitude; + uint16_t height; + uint32_t time; + uint32_t time_usec; +} pointing_data; + +void fill_packet_from_channels(pointing_data* packet); +void clear_packet_data(pointing_data* packet); +void get_acomp_shared_data_1hz(void); +void * send_pointing_data_acomp(void* args); + +#endif \ No newline at end of file diff --git a/mcp/communications/include/analysis_comp_trigger.h b/mcp/communications/include/analysis_comp_trigger.h new file mode 100644 index 000000000..02797ba7a --- /dev/null +++ b/mcp/communications/include/analysis_comp_trigger.h @@ -0,0 +1,31 @@ +/* analysis_comp_trigger.h: TIM data structures and function primals mcp to acomp 1 trigger data link + * + * This software is copyright (C) 2026 University of Arizona + * + * This file is part of the BLAST flight code licensed under the GNU + * General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef INCLUDE_ACOMP_TRIGGER_H +#define INCLUDE_ACOMP_TRIGGER_H + +#include "mcp.h" +#define ACOMP1_IP "192.168.1.6" +#define ACOMP_TRIGGER_PORT "1212" + +extern int16_t InCharge; + +struct trigger { + int take_data; +}; + +void acomp_countdown_1hz(void); +void * send_data_trigger_acomp(void* args); + + +#endif \ No newline at end of file diff --git a/mcp/include/command_struct.h b/mcp/include/command_struct.h index 26ae27f1f..a5ed78e73 100644 --- a/mcp/include/command_struct.h +++ b/mcp/include/command_struct.h @@ -422,6 +422,13 @@ typedef struct { float param5; } rfsoc_commands_t; +typedef struct { + int send_trigger; + int trigger_value; + int countdown; + int counting; +} acomp_trigger_t; + /** * @brief full command data structure containing relevant cross-mcp information for commanding @@ -543,6 +550,7 @@ struct CommandDataStruct { int update_position_sc; // should we automatically append lat/lon/alt to command packets cryo_command_t cryo_command; + acomp_trigger_t acomp_commands; rfsoc_commands_t rfsoc_commands1; rfsoc_commands_t rfsoc_commands2; diff --git a/mcp/mcp.c b/mcp/mcp.c index e1ef7acf5..37092ea37 100644 --- a/mcp/mcp.c +++ b/mcp/mcp.c @@ -104,6 +104,8 @@ #include "star_camera_solutions.h" #include "star_camera_receive.h" #include "star_camera_trigger.h" +#include "analysis_comp_sharing.h" +#include "analysis_comp_trigger.h" /* Define global variables */ char* flc_ip[2] = {"192.168.1.3", "192.168.1.4"}; @@ -364,6 +366,8 @@ static void mcp_1hz_routines(void) // commented out but will use when we have LJ subsystems again for power labjack_choose_execute(); // printf("InCharge is %d\n", InCharge); + get_acomp_shared_data_1hz(); + acomp_countdown_1hz(); store_1hz_acs(); record_motor_status_1hz(); // blast_store_disk_space(); @@ -674,6 +678,16 @@ blast_info("Finished initializing Beaglebones..."); */ } pthread_create(&cryo_tauhk_command_thread, NULL, send_cryo_commands, (void *) &cryo_tauhk_command_socket); + // Acomp stuff + pthread_t acomp_sharing_thread; + pthread_t acomp_trigger_thread; + struct socketData acomp_share_socket; + struct socketData acomp_trigger_socket; + populateSocketData(ACOMP1_IP, ACOMP_POINTING_PORT, &acomp_share_socket); + populateSocketData(ACOMP1_IP, ACOMP_TRIGGER_PORT, &acomp_trigger_socket); + pthread_create(&acomp_sharing_thread, NULL, send_pointing_data_acomp, (void *) &acomp_share_socket); + pthread_create(&acomp_trigger_thread, NULL, send_data_trigger_acomp, (void *) &acomp_trigger_socket); + // new star cam stuff // command setup pthread_t sc1_command_thread; From ed294edd289e452dddb23aea1e536ed879fbc31a Mon Sep 17 00:00:00 2001 From: Ian Lowe Date: Mon, 8 Jun 2026 10:19:16 -0700 Subject: [PATCH 4/6] modified pointing data thread to share at 200hz instead of 1hz so we can actually use the data for mapping... --- mcp/communications/analysis_comp_sharing.c | 2 +- mcp/communications/include/analysis_comp_sharing.h | 2 +- mcp/mcp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mcp/communications/analysis_comp_sharing.c b/mcp/communications/analysis_comp_sharing.c index 4d6f8aaae..174c421c5 100644 --- a/mcp/communications/analysis_comp_sharing.c +++ b/mcp/communications/analysis_comp_sharing.c @@ -136,7 +136,7 @@ void * send_pointing_data_acomp(void* args) { // first time setup of the socket is done } while (!proceed_with_loop_trigger) { - usleep(10000); + usleep(500); } fill_packet_from_channels(&acomp_packet); if (!strcmp(socket_target->ipAddr, ipAddr)) { diff --git a/mcp/communications/include/analysis_comp_sharing.h b/mcp/communications/include/analysis_comp_sharing.h index 593a0d1d7..5eb2e2c1f 100644 --- a/mcp/communications/include/analysis_comp_sharing.h +++ b/mcp/communications/include/analysis_comp_sharing.h @@ -32,7 +32,7 @@ typedef struct pointing_data { // need to finish designing this void fill_packet_from_channels(pointing_data* packet); void clear_packet_data(pointing_data* packet); -void get_acomp_shared_data_1hz(void); +void get_acomp_shared_data(void); void * send_pointing_data_acomp(void* args); #endif \ No newline at end of file diff --git a/mcp/mcp.c b/mcp/mcp.c index 37092ea37..66784be78 100644 --- a/mcp/mcp.c +++ b/mcp/mcp.c @@ -233,6 +233,7 @@ static void mcp_200hz_routines(void) store_200hz_acs(); command_motors(); write_motor_channels_200hz(); + get_acomp_shared_data(); SetGyroMask(); share_data(RATE_200HZ); framing_publish_200hz(); @@ -366,7 +367,6 @@ static void mcp_1hz_routines(void) // commented out but will use when we have LJ subsystems again for power labjack_choose_execute(); // printf("InCharge is %d\n", InCharge); - get_acomp_shared_data_1hz(); acomp_countdown_1hz(); store_1hz_acs(); record_motor_status_1hz(); From efd6d42f0d79b1eaaef502cbb3a0e6fb8c0074b7 Mon Sep 17 00:00:00 2001 From: Ian Lowe Date: Mon, 8 Jun 2026 10:26:33 -0700 Subject: [PATCH 5/6] fixed naming error --- mcp/communications/analysis_comp_sharing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcp/communications/analysis_comp_sharing.c b/mcp/communications/analysis_comp_sharing.c index 174c421c5..fbe0b6a35 100644 --- a/mcp/communications/analysis_comp_sharing.c +++ b/mcp/communications/analysis_comp_sharing.c @@ -78,7 +78,7 @@ void clear_packet_data(pointing_data* packet) { * computer is sending the data to the acomp * */ -void get_acomp_shared_data_1hz(void) { +void get_acomp_shared_data(void) { if (InCharge) { proceed_with_loop_trigger = 1; } From c73006ef7faa532053fe9474a6eab383b9a6f804 Mon Sep 17 00:00:00 2001 From: Ian Lowe Date: Thu, 11 Jun 2026 14:04:36 -0700 Subject: [PATCH 6/6] Fixes for Evan review --- mcp/communications/analysis_comp_sharing.c | 49 +++++++++-------- mcp/communications/analysis_comp_trigger.c | 52 ++++++++++--------- .../include/analysis_comp_sharing.h | 1 - .../include/analysis_comp_trigger.h | 1 - mcp/include/mcp.h | 4 ++ 5 files changed, 55 insertions(+), 52 deletions(-) diff --git a/mcp/communications/analysis_comp_sharing.c b/mcp/communications/analysis_comp_sharing.c index fbe0b6a35..fcfc7919e 100644 --- a/mcp/communications/analysis_comp_sharing.c +++ b/mcp/communications/analysis_comp_sharing.c @@ -109,31 +109,31 @@ void * send_pointing_data_acomp(void* args) { if ((returnval = getaddrinfo(socket_target->ipAddr, socket_target->port, &hints, &servinfo)) != 0) { blast_err("getaddrinfo: %s\n", gai_strerror(returnval)); return NULL; - } - // now we make a socket with this info - for (servinfoCheck = servinfo; servinfoCheck != NULL; servinfoCheck = servinfoCheck->ai_next) { - if ((sockfd = socket(servinfoCheck->ai_family, - servinfoCheck->ai_socktype, servinfoCheck->ai_protocol)) == -1) { - perror("talker: socket"); - continue; } - break; - } - // check to see if we made a socket - if (servinfoCheck == NULL) { - // set status to 0 (dead) if this fails - blast_err("talker: failed to create socket\n"); - return NULL; - } - // if we pass all of these checks then - // we set up the print statement vars - // need to cast the socket address to an INET still address - struct sockaddr_in *ipv = (struct sockaddr_in *)servinfo->ai_addr; - // then pass the pointer to translation and put it in a string - inet_ntop(AF_INET, &(ipv->sin_addr), ipAddr, INET_ADDRSTRLEN); - blast_info("IP target is: %s\n", ipAddr); - // now the "str" is packed with the IP address string - // first time setup of the socket is done + // now we make a socket with this info + for (servinfoCheck = servinfo; servinfoCheck != NULL; servinfoCheck = servinfoCheck->ai_next) { + if ((sockfd = socket(servinfoCheck->ai_family, + servinfoCheck->ai_socktype, servinfoCheck->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + break; + } + // check to see if we made a socket + if (servinfoCheck == NULL) { + // set status to 0 (dead) if this fails + blast_err("talker: failed to create socket\n"); + return NULL; + } + // if we pass all of these checks then + // we set up the print statement vars + // need to cast the socket address to an INET still address + struct sockaddr_in *ipv = (struct sockaddr_in *)servinfo->ai_addr; + // then pass the pointer to translation and put it in a string + inet_ntop(AF_INET, &(ipv->sin_addr), ipAddr, INET_ADDRSTRLEN); + blast_info("IP target is: %s\n", ipAddr); + // now the "str" is packed with the IP address string + // first time setup of the socket is done } while (!proceed_with_loop_trigger) { usleep(500); @@ -141,7 +141,6 @@ void * send_pointing_data_acomp(void* args) { fill_packet_from_channels(&acomp_packet); if (!strcmp(socket_target->ipAddr, ipAddr)) { length = sizeof(acomp_packet); - printf("length of packet is %d!!!!!!!\n", length); if ((bytes_sent = sendto(sockfd, &acomp_packet, length, 0, servinfo->ai_addr, servinfo->ai_addrlen)) == -1) { perror("talker: sendto"); diff --git a/mcp/communications/analysis_comp_trigger.c b/mcp/communications/analysis_comp_trigger.c index d3bbda935..5b2c5103b 100644 --- a/mcp/communications/analysis_comp_trigger.c +++ b/mcp/communications/analysis_comp_trigger.c @@ -38,8 +38,10 @@ void acomp_countdown_1hz(void) { if (CommandData.acomp_commands.counting == 1) { if (CommandData.acomp_commands.countdown == 0) { + CommandData.acomp_commands.counting = 0; CommandData.acomp_commands.send_trigger = 1; CommandData.acomp_commands.trigger_value = 0; + return; } CommandData.acomp_commands.countdown--; } @@ -72,33 +74,33 @@ void * send_data_trigger_acomp(void* args) { if ((returnval = getaddrinfo(socket_target->ipAddr, socket_target->port, &hints, &servinfo)) != 0) { blast_err("getaddrinfo: %s\n", gai_strerror(returnval)); return NULL; - } - // now we make a socket with this info - for (servinfoCheck = servinfo; servinfoCheck != NULL; servinfoCheck = servinfoCheck->ai_next) { - if ((sockfd = socket(servinfoCheck->ai_family, - servinfoCheck->ai_socktype, servinfoCheck->ai_protocol)) == -1) { - perror("talker: socket"); - continue; } - break; - } - // check to see if we made a socket - if (servinfoCheck == NULL) { - // set status to 0 (dead) if this fails - blast_err("talker: failed to create socket\n"); - return NULL; - } - // if we pass all of these checks then - // we set up the print statement vars - // need to cast the socket address to an INET still address - struct sockaddr_in *ipv = (struct sockaddr_in *)servinfo->ai_addr; - // then pass the pointer to translation and put it in a string - inet_ntop(AF_INET, &(ipv->sin_addr), ipAddr, INET_ADDRSTRLEN); - blast_info("IP target is: %s\n", ipAddr); - // now the "str" is packed with the IP address string - // first time setup of the socket is done + // now we make a socket with this info + for (servinfoCheck = servinfo; servinfoCheck != NULL; servinfoCheck = servinfoCheck->ai_next) { + if ((sockfd = socket(servinfoCheck->ai_family, + servinfoCheck->ai_socktype, servinfoCheck->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + break; + } + // check to see if we made a socket + if (servinfoCheck == NULL) { + // set status to 0 (dead) if this fails + blast_err("talker: failed to create socket\n"); + return NULL; + } + // if we pass all of these checks then + // we set up the print statement vars + // need to cast the socket address to an INET still address + struct sockaddr_in *ipv = (struct sockaddr_in *)servinfo->ai_addr; + // then pass the pointer to translation and put it in a string + inet_ntop(AF_INET, &(ipv->sin_addr), ipAddr, INET_ADDRSTRLEN); + blast_info("IP target is: %s\n", ipAddr); + // now the "str" is packed with the IP address string + // first time setup of the socket is done } - if (CommandData.acomp_commands.send_trigger == 1 && InCharge) { + if ((CommandData.acomp_commands.send_trigger == 1) && InCharge) { acomp_trigger.take_data = CommandData.acomp_commands.trigger_value; // pull the value into the packet CommandData.acomp_commands.send_trigger = 0; // don't try to send again if (!strcmp(socket_target->ipAddr, ipAddr)) { diff --git a/mcp/communications/include/analysis_comp_sharing.h b/mcp/communications/include/analysis_comp_sharing.h index 5eb2e2c1f..a90f4cbce 100644 --- a/mcp/communications/include/analysis_comp_sharing.h +++ b/mcp/communications/include/analysis_comp_sharing.h @@ -15,7 +15,6 @@ #define INCLUDE_ACOMP_SHARING_H #include "mcp.h" -#define ACOMP1_IP "192.168.1.6" #define ACOMP_POINTING_PORT "1213" extern int16_t InCharge; diff --git a/mcp/communications/include/analysis_comp_trigger.h b/mcp/communications/include/analysis_comp_trigger.h index 02797ba7a..fbe9b8d74 100644 --- a/mcp/communications/include/analysis_comp_trigger.h +++ b/mcp/communications/include/analysis_comp_trigger.h @@ -15,7 +15,6 @@ #define INCLUDE_ACOMP_TRIGGER_H #include "mcp.h" -#define ACOMP1_IP "192.168.1.6" #define ACOMP_TRIGGER_PORT "1212" extern int16_t InCharge; diff --git a/mcp/include/mcp.h b/mcp/include/mcp.h index d178b79b2..7e76d9d53 100644 --- a/mcp/include/mcp.h +++ b/mcp/include/mcp.h @@ -48,6 +48,10 @@ void force_incharge(void); #define DEFAULT_INCHARGE !SouthIAm +// TIM analysis computer IP Addrs +#define ACOMP1_IP "192.168.1.6" +#define ACOMP2_IP "192.168.1.7" + // telemetry defines // how many options we have