{"action":"created","issue":{"url":"https://api.github.com/repos/JSBSim-Team/jsbsim/issues/74","repository_url":"https://api.github.com/repos/JSBSim-Team/jsbsim","labels_url":"https://api.github.com/repos/JSBSim-Team/jsbsim/issues/74/labels{/name}","comments_url":"https://api.github.com/repos/JSBSim-Team/jsbsim/issues/74/comments","events_url":"https://api.github.com/repos/JSBSim-Team/jsbsim/issues/74/events","html_url":"https://github.com/JSBSim-Team/jsbsim/issues/74","id":334848131,"node_id":"MDU6SXNzdWUzMzQ4NDgxMzE=","number":74,"title":"Output data via socket to an external server and wait for reply on an input socket","user":{"login":"agodemar","id":819499,"node_id":"MDQ6VXNlcjgxOTQ5OQ==","avatar_url":"https://avatars1.githubusercontent.com/u/819499?v=4","gravatar_id":"","url":"https://api.github.com/users/agodemar","html_url":"https://github.com/agodemar","followers_url":"https://api.github.com/users/agodemar/followers","following_url":"https://api.github.com/users/agodemar/following{/other_user}","gists_url":"https://api.github.com/users/agodemar/gists{/gist_id}","starred_url":"https://api.github.com/users/agodemar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agodemar/subscriptions","organizations_url":"https://api.github.com/users/agodemar/orgs","repos_url":"https://api.github.com/users/agodemar/repos","events_url":"https://api.github.com/users/agodemar/events{/privacy}","received_events_url":"https://api.github.com/users/agodemar/received_events","type":"User","site_admin":false},"labels":[{"id":781284037,"node_id":"MDU6TGFiZWw3ODEyODQwMzc=","url":"https://api.github.com/repos/JSBSim-Team/jsbsim/labels/enhancement","name":"enhancement","color":"84b6eb","default":true},{"id":781284043,"node_id":"MDU6TGFiZWw3ODEyODQwNDM=","url":"https://api.github.com/repos/JSBSim-Team/jsbsim/labels/question","name":"question","color":"cc317c","default":true}],"state":"open","locked":false,"assignee":{"login":"agodemar","id":819499,"node_id":"MDQ6VXNlcjgxOTQ5OQ==","avatar_url":"https://avatars1.githubusercontent.com/u/819499?v=4","gravatar_id":"","url":"https://api.github.com/users/agodemar","html_url":"https://github.com/agodemar","followers_url":"https://api.github.com/users/agodemar/followers","following_url":"https://api.github.com/users/agodemar/following{/other_user}","gists_url":"https://api.github.com/users/agodemar/gists{/gist_id}","starred_url":"https://api.github.com/users/agodemar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agodemar/subscriptions","organizations_url":"https://api.github.com/users/agodemar/orgs","repos_url":"https://api.github.com/users/agodemar/repos","events_url":"https://api.github.com/users/agodemar/events{/privacy}","received_events_url":"https://api.github.com/users/agodemar/received_events","type":"User","site_admin":false},"assignees":[{"login":"agodemar","id":819499,"node_id":"MDQ6VXNlcjgxOTQ5OQ==","avatar_url":"https://avatars1.githubusercontent.com/u/819499?v=4","gravatar_id":"","url":"https://api.github.com/users/agodemar","html_url":"https://github.com/agodemar","followers_url":"https://api.github.com/users/agodemar/followers","following_url":"https://api.github.com/users/agodemar/following{/other_user}","gists_url":"https://api.github.com/users/agodemar/gists{/gist_id}","starred_url":"https://api.github.com/users/agodemar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agodemar/subscriptions","organizations_url":"https://api.github.com/users/agodemar/orgs","repos_url":"https://api.github.com/users/agodemar/repos","events_url":"https://api.github.com/users/agodemar/events{/privacy}","received_events_url":"https://api.github.com/users/agodemar/received_events","type":"User","site_admin":false},{"login":"seanmcleod","id":824856,"node_id":"MDQ6VXNlcjgyNDg1Ng==","avatar_url":"https://avatars3.githubusercontent.com/u/824856?v=4","gravatar_id":"","url":"https://api.github.com/users/seanmcleod","html_url":"https://github.com/seanmcleod","followers_url":"https://api.github.com/users/seanmcleod/followers","following_url":"https://api.github.com/users/seanmcleod/following{/other_user}","gists_url":"https://api.github.com/users/seanmcleod/gists{/gist_id}","starred_url":"https://api.github.com/users/seanmcleod/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/seanmcleod/subscriptions","organizations_url":"https://api.github.com/users/seanmcleod/orgs","repos_url":"https://api.github.com/users/seanmcleod/repos","events_url":"https://api.github.com/users/seanmcleod/events{/privacy}","received_events_url":"https://api.github.com/users/seanmcleod/received_events","type":"User","site_admin":false},{"login":"bcoconni","id":7502904,"node_id":"MDQ6VXNlcjc1MDI5MDQ=","avatar_url":"https://avatars2.githubusercontent.com/u/7502904?v=4","gravatar_id":"","url":"https://api.github.com/users/bcoconni","html_url":"https://github.com/bcoconni","followers_url":"https://api.github.com/users/bcoconni/followers","following_url":"https://api.github.com/users/bcoconni/following{/other_user}","gists_url":"https://api.github.com/users/bcoconni/gists{/gist_id}","starred_url":"https://api.github.com/users/bcoconni/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bcoconni/subscriptions","organizations_url":"https://api.github.com/users/bcoconni/orgs","repos_url":"https://api.github.com/users/bcoconni/repos","events_url":"https://api.github.com/users/bcoconni/events{/privacy}","received_events_url":"https://api.github.com/users/bcoconni/received_events","type":"User","site_admin":false}],"milestone":null,"comments":3,"created_at":"2018-06-22T11:42:22Z","updated_at":"2018-06-23T23:20:29Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"Here I collect the main points of a previous discussion in a closed PR #72 .\r\n\r\n**The idea**\r\nThe idea comes from [this research article](http://www.mdpi.com/2226-4310/5/2/42) demonstrating how JSBSim can be used to run flight simulations in presence of a gust field pre-calculated with [OpenFOAM](https://openfoam.org/). This is what I do:\r\n-  The chosen aircraft model is flown through a volumetric CFD mesh. Each node in the grid owns three cartesian components of the local wind.\r\n- At each step of the FDM propagation, JSBSim sends the aircraft actual position (lat, lon, agl-altitude) to an external server application on an output TCP socket. \r\n- *JSBSim blocks time propagation and waits for server reply*.\r\n- The server reads and transforms the received geographic position in a triplet of Cartesian coordinates then accesses the velocity field associated to the mesh and calculates the local wind velocity by interpolation.\r\n- The server sends back *on the same socket* (in that case) the wind velocity.\r\n- JSBSim sets the new values of the properties: `atmosphere/wind-north-fps`, `atmosphere/wind-east-fps`, and `atmosphere/wind-down-fps`.\r\n- The FDM propagation continues.\r\n\r\n**Configuration**\r\nThe O/I can be configures via the `<output/>` and `<input/>` tags as follows:\r\n```xml\r\n<!-- e.g. in file scripts/C1723.xml -->\r\n<output name=\"localhost\" type=\"SOCKET\" port=\"1138\" rate=\"20\" file=\"uniconversions.xml\">\r\n  <property> position/lat-gc-deg </property>\r\n  <property> position/long-gc-deg </property>\r\n  <property apply=\"convert-ft-To-m\" caption=\"position/h-agl-meters\"> position/h-agl-ft </property>\r\n</output>\r\n<input type=\"SOCKET\" port=\"1139\" />\r\n```\r\n\r\n**Strategy**\r\n\r\nThe server application (OpenFOAM server) should do most of the work. **By design, the OpenFOAM server has to manage asynchronously several running instances of JSBSim** (e.g. hundreds, or thousands) providing them the wind data according to aircraft positions in the flow field.\r\n\r\nOn the initial iteration of the sim loop the JSBSim input socket doesn't have an incoming connection yet, it's still waiting for a connection. So it doesn't block in this case it simply returns.\r\n\r\nThen at the end of the first iteration of the sim loop the output socket sends the initial aircraft state to the OpenFOAM server. The OpenFOAM server on receiving this initial incoming connection now knows the IP address of JSBSim and so it then creates a connection to the input socket (with some configured port number, i.e. 1139) that is waiting for connections. And it sends back it's first set of wind velocities.\r\n\r\nSo now on the next iteration of the sim loop the input socket will be connected and it will issue a blocking read to retrieve the OpenFOAM set commands for the wind velocities etc. and will process them and return allowing the sim loop to now continue in lock-step with the OpenFOAM server.\r\n\r\n**Issue**\r\nGlancing at the socket code a bit it looks like currently for the input socket case the socket passed to the accept() API is set to non-blocking, so it won't block waiting for a connection. The socket passed to the recv() API is also set to non-blocking after a successful accept().\r\n\r\nFor the OpenFOAM case/example it is not critical that the very first sim loop iteration needs data from the OpenFOAM server.\r\n\r\n**There may be some cases where it is critical that JSBSim has to receive the input data from the external server on the very first simulation loop iteration. To handle that case we could potentially have multiple flags for the input socket which specify blocking versus non-blocking for the accept() and the recv() calls independently.**\r\n\r\nSo for the OpenFOAM example one would leave the `accept()` as non-blocking but set `recv()` blocking. For another server where the initial data is critical one would set *both* `accept()` and `recv()` to blocking. In which case JSBSim would start up but block until the external server connected and sent the first packet."},"comment":{"url":"https://api.github.com/repos/JSBSim-Team/jsbsim/issues/comments/399717063","html_url":"https://github.com/JSBSim-Team/jsbsim/issues/74#issuecomment-399717063","issue_url":"https://api.github.com/repos/JSBSim-Team/jsbsim/issues/74","id":399717063,"node_id":"MDEyOklzc3VlQ29tbWVudDM5OTcxNzA2Mw==","user":{"login":"agodemar","id":819499,"node_id":"MDQ6VXNlcjgxOTQ5OQ==","avatar_url":"https://avatars1.githubusercontent.com/u/819499?v=4","gravatar_id":"","url":"https://api.github.com/users/agodemar","html_url":"https://github.com/agodemar","followers_url":"https://api.github.com/users/agodemar/followers","following_url":"https://api.github.com/users/agodemar/following{/other_user}","gists_url":"https://api.github.com/users/agodemar/gists{/gist_id}","starred_url":"https://api.github.com/users/agodemar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agodemar/subscriptions","organizations_url":"https://api.github.com/users/agodemar/orgs","repos_url":"https://api.github.com/users/agodemar/repos","events_url":"https://api.github.com/users/agodemar/events{/privacy}","received_events_url":"https://api.github.com/users/agodemar/received_events","type":"User","site_admin":false},"created_at":"2018-06-23T23:20:29Z","updated_at":"2018-06-23T23:20:29Z","author_association":"CONTRIBUTOR","body":"@bcoconni \r\n> My suggestion would then be to create a new class that inherits `FGInputSocket` and which method `InitModel()` would be overloaded to execute a sequence similar to the above.\r\n\r\nWould you please post here a skeleton of the class you have in mind?"}}
{"actor":{"display_login":"agodemar"}}