To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.nqcOpen lugnet.robotics.rcx.nqc in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / NQC / 1142
1141  |  1143
Subject: 
Re: NQC vs Spirit communication speed
Newsgroups: 
lugnet.robotics.rcx.nqc
Date: 
Fri, 11 May 2001 20:48:22 GMT
Viewed: 
2345 times
  
In article <GD6pCC.JqM@lugnet.com>, "John Hansen" <JohnBinder@aol.com>
wrote:


Dynamic timing doesn't function if predictive replies are enabled:

bool dynamic = (timeout==0) && fDynamicTimeout && !fPredictive;

In the SetTarget method you set both of them to true.  So unless I'm
missing
something (a definite possibility) your code never does dynamic timeouts

Correct - dynamic timing is turned off when predictive is being used
(which is the default).  Predictive is relatively new, and I wasn't sure
which code you started with (or how you ported/used it), so that's why I
explained the dynamic timing.  From what  you've said, it sounds like
predictive is active for you.

-
except when downloading the firmware when it explicitly turns off
predictive
replies temporarily.  Couldn't you still dynamically adjust the timeout
when
predictive replies are enabled?


Dynamic timeout and predictive are two different ways of solving the
same problem - namely when to call a received packet "complete".

Since I wasn't sure how well predictive was going to work out, I
introduced it (back at 2.2 I think) in a way that made it easy to
disable and/or remove.  Then I forgot about finishing it :)

In the current code, where predictive isn't 100% accurate, I guess a
hybrid predictive/dynamic would help (only use dynamic when predictive
doesn't know how long the packet will be).  I think a better approach
would be to make predictive more accurate so that dynamic would only be
needed when predictive is disabled (fast firmware download).

I went through all of the RCX/CM/Scout bytecodes and believe the
following function is accurate for all current bytecodes:

int PredictReplyLength(const UByte *data, int length)
{
   switch(data[0] & 0xf7)
   {
      case 0x25:  // __task
      case 0x35:
      case 0x45:  // __dl
      case 0x75:
         return 1;
      case 0x30:  // pollb
      case 0x12:  // poll
         return 2;
      case 0x15:
         return 8;
      case 0xa5:
         return 25;
      case 0x20:
         return 188;
      case 0x63:  // pollm
         if (length != 4) return 0;
         return data[3];
      case 0xa4:  // upload datalog
         if (length != 5) return 0;
         return (data[3] + ((int)data[4] << 8)) * 3;
      default:
         return 0;
   }
}


The potential risk is that a new opcode might get introduced that has
reply data, and PredictReplyLenght() won't know it and think it has 0
bytes of reply data.  Two potential failure modes:

* The first data byte - by coincidence - just happens to complete the
checksum, and there's enough delay after this byte (before the next data
byte) that the reply gets checked.  In this case, a false match will
happen, the Tx will be successful, but reply data gets thrown out.

* Any other situation - any predictive match would fail, so the default
timeout would get used (reliable, but slow).

One workaround would be to add cases for all bytecodes with 0 reply
data, rather than making 0 the default (or use a table instead of a
switch).  Then the default could return a huge number (effectively
getting rid of the first failure mode, but insuring the second).  Better
would be to indicate that its an unknown bytecode, and resort back to
dynamic timing (hybrid approach).  However, all of this seems like a lot
of work.  Out of about 100 bytecodes, only 11 aren't 0, and 10 of those
were part of the original RCX (the 11th was added for Scout and RCX2).
Its not like new replies are getting introduced every day.  If lego
introduces new bytecodes with reply data, I'll just add cases to the
switch later on.


I haven't done a good job of precisely measuring delays.  I'd estimate
almost a half-second delay in many instances.  That may correlate to the
400
millisecond timeout that I've noticed when I stepped through the code.

No need to measure.  I tried it myself with poll (0x12) and noticed the
400ms delay.  Fixing the predictive codes eliminated this (scrolls too
fast to notice now).  If you're still seeing delays after using the new
predictive function, then measure it and let me know.   But it really
sounds like the 400ms max delay that gets used for predictive.

Dave Baum

--
reply to: dbaum at enteract dot com



Message has 1 Reply:
  Re: NQC vs Spirit communication speed
 
(...) I made PredictReplyLength a member of the RCXLink class so it can return a different value for case 0x20 (it returns 20 if the Target is Cybermaster and 0 if it is Scout - since the Scout doesn't support that opcode). Of course, in Object (...) (23 years ago, 11-May-01, to lugnet.robotics.rcx.nqc)

Message is in Reply To:
  Re: NQC vs Spirit communication speed
 
(...) I'm using AutoLink.Send for most things. Initially I was always closing the link at the end of each method (which mostly map to the Spirit OCX API). I've made that configurable and at present I'm running with it set to leave the link open. (...) (23 years ago, 11-May-01, to lugnet.robotics.rcx.nqc)

8 Messages in This Thread:



Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact

This Message and its Replies on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR