예제 #1
0
        public bool call(RosMessage req, ref RosMessage resp)
        {
            if (resp == null)
            {
                //instantiate null response IN CASE this call succeeds
                resp = RosMessage.Generate(req.MessageType.Replace("Request", "Response"));
            }

            CallInfo info = new CallInfo {
                req = req, resp = resp, success = false, finished = false
            };

            bool immediate = false;

            lock ( call_queue_mutex )
            {
                if (connection.dropped)
                {
                    return(false);
                }

                if (call_queue.Count == 0 && header_written && header_read)
                {
                    immediate = true;
                }

                call_queue.Enqueue(info);
            }

            if (immediate)
            {
                processNextCall();
            }

            while (!info.finished)
            {
                ROS.Debug()($"[{ThisNode.Name}] info.finished_condition.WaitOne();");
                info.finished_condition.WaitOne();
            }

            if (info.success)
            {
                // response is only sent on success => don't try to deserialize on failure.
                resp.Deserialize(resp.Serialized);
            }

            if (!string.IsNullOrEmpty(info.exception))
            {
                ROS.Error()($"[{ThisNode.Name}] Service call failed: service [{name}] responded with an error: {info.exception}");
            }
            return(info.success);
        }
예제 #2
0
        public async Task <(bool, RosMessage)> Call(RosMessage request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            RosMessage response = RosMessage.Generate(request.MessageType.Replace("Request", "Response"));

            if (response == null)
            {
                throw new Exception("Response message generation failed.");
            }

            var queue = callQueue;

            try
            {
                var call = new CallInfo {
                    Request = request, Response = response
                };
                await queue.OnNext(call, cancel).ConfigureAwait(false);

                bool success = await call.AsyncResult.ConfigureAwait(false);

                if (success)
                {
                    // response is only sent on success
                    response.Deserialize(response.Serialized);
                }

                return(success, response);
            }
            catch (Exception e)
            {
                string message = $"Service call failed: service [{name}] responded with an error: {e.Message}";
                ROS.Error()(message);
                return(false, null);
            }
            finally
            {
                if (!persistent)
                {
                    queue.OnCompleted();
                }
            }
        }
예제 #3
0
        internal long HandleMessage(
            RosMessage msg,
            bool ser,
            bool nocopy,
            IDictionary <string, string> connectionHeader,
            PublisherLink link
            )
        {
            RosMessage t            = null;
            long       drops        = 0;
            TimeData   receipt_time = ROS.GetTime().data;

            if (msg.Serialized != null) // will be null if self-subscribed
            {
                msg.Deserialize(msg.Serialized);
            }

            lock (gate)
            {
                foreach (CallbackInfo info in callbacks)
                {
                    string ti = info.Helper.type;
                    if (nocopy || ser)
                    {
                        t = msg;
                        t.connection_header = msg.connection_header;
                        t.Serialized        = null;
                        bool wasFull            = false;
                        bool nonconst_need_copy = callbacks.Count > 1;
                        info.SubscriptionQueue.AddToCallbackQueue(info.Helper, t, nonconst_need_copy, ref wasFull, receipt_time);
                        if (wasFull)
                        {
                            ++drops;
                        }
                        else
                        {
                            info.CallbackQueue.AddCallback(info.SubscriptionQueue, info.SubscriptionQueue);
                        }
                    }
                }
            }

            if (t != null && link.Latched)
            {
                LatchInfo li = new LatchInfo
                {
                    Message          = t,
                    Link             = link,
                    ConnectionHeader = connectionHeader,
                    ReceiptTime      = receipt_time
                };
                if (latchedMessages.ContainsKey(link))
                {
                    latchedMessages[link] = li;
                }
                else
                {
                    latchedMessages.Add(link, li);
                }
            }

            return(drops);
        }