What I am attempting to do has been done before, use FG as a scene generator for my own hardware in a cockpit simulator.
The hardware pipes to a 'client' computer that is attempting to create a socket connection the the FG 'server' (just passing data into FG right now)
i execute >fgfs --generic=socket,in,45,localhost,5040,tcp,input_xml as my starting command (i have also played around with a udp socket, however that gives less feedback on whether or not a connection has been established and as that is my problem I was hoping to start by establishing a tcp connection, especially after successfully connecting via telnet interface on my redhat virtual machine)
my client side c code looks like this:
- Code: Select all
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define PORT "3490"
int main(int argc, char* argv[])
{
int sock_in, sock_out;
int addr_len, bytes_read;
char recv_data[1024];
struct sockaddr_in server_addr_in , client_addr_in;
struct sockaddr_in server_addr_out;
struct addrinfo hints, *servinfo, *p;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
int rv, sockfd;
/*error check argument inputs*/
if (argc != 2) {
printf("meant to connect to server IP!\n");
return 1;
}
/*
error check get addr info, else put into servinfo
currently: 10.1.12.128 and PORT is 5001
*/
char msg[10];
sprintf(msg, "%d", htons(3490));
if ((rv = getaddrinfo(argv[1], ((char *) msg) , &hints, &servinfo)) != 0) {
printf("getaddrinfo failed! rv = %d \n",rv);
printf("error def: %s\n", gai_strerror(rv));
return -1;
} else {
printf("addr info obtained!\n");
}
/*error check and initialize obtaining sockfd*/
if ((sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, 0)) == -1) {
printf("socket file descriptor init failed\n");
printf("error def: %s\n", gai_strerror(sockfd));
return 1;
} else {
printf("socket file descriptor obtained!\n");
}
/*error check and intialize connection to fg server*/
if ((rv = connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen)) < 0) {
close(sockfd);
printf("connection failed to open\n");
printf("error number is: %d def: %s\n", errno, gai_strerror(errno));
return 1;
} else {
printf("socket connect!\n");
}
return 0;
}
when I execute the code it just hangs at the call to connect.
my udp implementation attempted to set position/altitude-ft as error check and that looked like this
- Code: Select all
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define PORT "5010"
int main(int argc, char* argv[])
{
int addr_len, bytes_read;
char recv_data[1024];
char send_data[1024];
struct addrinfo hints, *servinfo, *p;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
int rv, sockfd;
int msg_len = 0;
float altitude = 10000;
/*error check argument inputs*/
if (argc != 2) {
printf("meant to connect to server IP!\n");
return 1;
}
/*
error check get addr info, else put into servinfo
currently: 10.1.12.128 and PORT is 5001
*/
if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
printf("getaddrinfo failed! rv = %d \n",rv);
printf("error def: %s\n", gai_strerror(rv));
return -1;
} else {
printf("addr info obtained!\n");
}
/*error check and initialize obtaining sockfd*/
if ((sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1) {
printf("socket file descriptor init failed\n");
printf("error def: %s\n", gai_strerror(sockfd));
return 1;
} else {
printf("socket file descriptor obtained!\n");
}
/*error check and intialize connection to fg server*/
if ((rv = connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen)) < 0) {
close(sockfd);
printf("connection failed to open\n");
printf("error number is: %d def: %s\n", errno, gai_strerror(errno));
return 1;
} else {
printf("no error in datagram socket connect!\n");
}
msg_len = sprintf(send_data, "%.2f\n", altitude);
// Print Control inputs to stdout
printf("\nSetting alititude to:\n%s\n", send_data);
// Send UDP packet
printf("attempting to send %d bytes of data \n", msg_len);
send(sockfd, send_data, msg_len, 0);
return 0;
}
with an xml struct titled input_protocol of (sorry for comments, trying to keep everything striaght)
- Code: Select all
<?xml version="1.0"?>
<PropertyList>
<generic>
<input>
<!--
!!!!IMPORTANT!!!!!
make sure to save edits to this copy into
C:\Program Files\FlightGear 2018.2.2\data\Protocol
!!!!IMPORTANT!!!!!
-->
<line_separator>newline</line_separator> <!-- used at the end of sprintf statements-->
<!-- <var_separator>tab</var_separator> only needed for mulitple cars--><!-- used between vars packed within an sprintf -->
<!-- <binary_mode>true</binary_mode> comment this line back to swith to binary -->
<chunk>
<name>/position/altitude-ft</name>
<type>float</type>
<node>/position/altitude-ft</node>
<!-- <format>%f</format> only for outputs i believe-->
</chunk>
<!--not using this chunk rn
<chunk>
<name>/controls/flight/elevator</name>
<node>/controls/flight/elevator</node>
<type>float</type>
<format>%f</format>
</chunk>
-->
</input>
</generic>
</PropertyList>
that i called in command line with >fgfs --generic=socket,in,45,localhost,udp,input_protocol (which was placed in protocol directory)
i received no feedback from this one (expect to see change in height)
I am posting as a continuation of viewtopic.php?f=17&t=33381 where it seemed the poster could only solve his issue via integrating hardware and pushing socket data via serial connection to the computer. @Hooray seemed to suggest that this is a neccesary workaround (unless I misunderstood).
Let me know if you need any more information! This is an awesome platform with a cool community that I would love to develop for.