Announcement

Collapse
No announcement yet.

Please Help, problem with buffer overwriting when writing to our cloned Legacy Module

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • pbrier
    replied
    Would it be a suggestion to also use the (excellent) github issue tracker as the public gateway to report and track bugs.?

    This would allow teams to see wat is known about issues so they can contribute to testing and solving them. The can also see wat is solved in a given release of the SDK and not spend a long time on known issues and they can also asses the impact of changes in the SDK on their code.

    Leave a comment:


  • Jonathan Berling
    replied
    Originally posted by pbrier View Post
    Great work!

    Btw wat is the "official" procedure for a bug reports?
    Will you just follow the forum or is a github issue the preferred route?
    I monitor the forums pretty closely. I don't always have time to respond, but if I see an issue I create a ticket on our internal issue tracker.

    Leave a comment:


  • HagertyRobotics
    replied
    Thanks Jonathan! I hit send and then saw your post.

    That is great because we were pulling our hair out trying to figure out what was wrong.

    Leave a comment:


  • HagertyRobotics
    replied
    Originally posted by dmssargent View Post
    So, if the Start method only writes one register does that register become valid, or the nothing in the Start method work regarding writing out to the your Legacy Module? Can you sniff for any corruption coming out of the "robot" and into the "Legacy Module"?
    Correct, none of the registers written in the start method become valid when there are writes happening in the loop().

    We just tried an experiment to see if we put a delay after the start() method, would it cause a "write buffer" to be called and allow the writes in the start() method to be executed. To do this we just skipped writing during the first loop() pass. This worked and allowed the write in the start method to be written to the Legacy Module. Below is the code that works. Note: the RESET_ENCODER write in the start() method was still masked by the SetTargetPosition(10000) and the targetPosition register was not written.

    Code:
    	public void start() {
    		motorRight = hardwareMap.dcMotor.get("right");
    		motorLeft = hardwareMap.dcMotor.get("left");
    		//motorLeft.setDirection(DcMotor.Direction.REVERSE);
    
    		wheelController = hardwareMap.dcMotorController.get("wheels");
    
    		motorLeft.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
    		motorLeft.setTargetPosition(100000);
    	}
    
    	/*
    	 * This method will be called repeatedly in a loop
    	 * 
    	 * @see com.qualcomm.robotcore.eventloop.opmode.OpMode#run()
    	 */
    	@Override
    	public void loop() {
    
    		if (loops++ > 0) { // skip first loop;  Loop initialized to 0 in class.
    			motorLeft.setPower(0.10);
    			motorRight.setPower(0.20);
    		}
    	}
    The question of whether there is an I/O cycle between start() and loop() was discussed in an earlier thread http://ftcforum.usfirst.org/showthre...Start()-method I think Jonathan Berling said that there was an I/O cycle between but we are not seeing the effects of it.

    Could anyone try it on a real Core Legacy Module and see if the encoders get reset, with and without the first loop delay.
    Could anyone check the code in the SDK (follow a setPower() call for each implementation until you get to the queue write call)

    Thanks

    Leave a comment:


  • pbrier
    replied
    Great work!

    Btw wat is the "official" procedure for a bug reports?
    Will you just follow the forum or is a github issue the preferred route?

    Leave a comment:


  • Jonathan Berling
    replied
    Thanks HagertyRobotics for the very clear bug report. With it we were able to quickly locate the bug with the legacy module driver.

    What is happening is during the loop method only the last write to a given NXT device is being saved. All other writes are being lost. This bug was introduced about a week before the beta code went live. The USB Motor / Servo controller do not see this bug.

    Obviously this is a high priority bug.

    Leave a comment:


  • dmssargent
    replied
    So, if the Start method only writes one register does that register become valid, or the nothing in the Start method work regarding writing out to the your Legacy Module? Can you sniff for any corruption coming out of the "robot" and into the "Legacy Module"?

    Leave a comment:


  • HagertyRobotics
    replied
    I'm sorry, the value of left and right are defined and initialized above as member variables of the class.

    Don't worry so much about that example. The bigger problem we are having is when writes are done in the Start() method that don't get written. Or when you need to write multiple registers and the values change each loop iteration the cache is always invalid.

    Thanks

    Leave a comment:


  • pbrier
    replied
    Can you share the code of the interface so we can help debugging?

    Leave a comment:


  • dmssargent
    replied
    dlevy is right about that if the left or right variable are being set to a value before the increment expression is reached the incrementing expression may always be the same. I was getting to the true/false bit in objects like cin (C++) messed up with operator expressions.

    Here is C++: (not that the OP needs it, but it gives a explanation of what it is doing)
    pre-increment and pre-decrement operators increments or decrements the value of the object and returns a reference to the result.
    post-increment and post-decrement creates a copy of the object, increments or decrements the value of the object and returns the copy from before the increment or decrement.
    http://en.cppreference.com/w/cpp/lan...perator_incdec

    Here is the Java:
    The increment/decrement operators can be applied before (prefix) or after (postfix) the operand. The code result++; and ++result; will both end in result being incremented by one. The only difference is that the prefix version (++result) evaluates to the incremented value, whereas the postfix version (result++) evaluates to the original value. If you are just performing a simple increment/decrement, it doesn't really matter which version you choose. But if you use this operator in part of a larger expression, the one that you choose may make a significant difference.
    http://docs.oracle.com/javase/tutori...bolts/op1.html

    Can you post the entire loop code, post a link to it in GitHub or Pastebin, or are you just using the orignal K9 Tank Drive OpMode with the previously mentioned modification?

    Leave a comment:


  • dlevy
    replied
    Originally posted by dmssargent View Post
    I believe what dlevy was saying was the left++ does not return an incremented value of 1.
    That's true. If you want the setPower to receive the incremented value you can also use :
    Code:
    setPower(++left);
    instead of
    Code:
    left++.
    setPower(left);
    However my point was that left++ would indeed be incremented but that incremented value would not be retained over multiple calls to loop() if the variable is being reset earlier in the method i.e. "float left = -gamepad1.left_stick_y;"

    Example
    Code:
    loop() {
       float left =1;
    ......
       left++
    }


    The value of left would always be 2 not matter how many times loop() is called.

    Leave a comment:


  • HagertyRobotics
    replied
    Originally posted by dmssargent View Post
    I believe what dlevy was saying was the left++ does not return an incremented value of 1. I believe that (left++ sets the left to left plus one and returns true (1) if it succeeded. Also, I believe the values written to the motor speeds and hardware are not applied until the loop terminates, if what I read was correct.
    So, maybe, that loop should be:
    Code:
     
    loop() {
        //Increment the left variable, and set the motor speed to the value of the variable.
        left++;
        motorLeft.setPower(left);
    
        //Increment the right variable, and set the motor speed to the value of the variable.
        right++;
        motorRight.setPower(right);
    }
    Also, that TI Lauchpad package for emulating a Core Legacy Module could be made open source to better facilitate helping with your project.
    Thanks dmssargent,

    I'm sorry about the typo, should be motorLeft.setPower(left++). The left++ will return the current value of left before incrementing left.

    We tried your code above with the same result.

    left right
    0 0
    0 1
    0 2
    0 3
    0 4

    Yes, the motor values are written to the output buffer at the end of the loop. They are using at FIFO Queue to queue up the writes but the last write is overwriting the previous.

    We will work on posting the source.

    Leave a comment:


  • dmssargent
    replied
    I believe what dlevy was saying was the left++ does not return an incremented value of 1. I believe that (left++ sets the left to left plus one and returns true (1) if it succeeded. Also, I believe the values written to the motor speeds and hardware are not applied until the loop terminates, if what I read was correct.
    So, maybe, that loop should be:
    Code:
     
    loop() {
        //Increment the left variable, and set the motor speed to the value of the variable.
        left++;
        motorLeft.setPower(left);
    
        //Increment the right variable, and set the motor speed to the value of the variable.
        right++;
        motorRight.setPower(right);
    }
    Also, that TI Lauchpad package for emulating a Core Legacy Module could be made open source to better facilitate helping with your project.

    Leave a comment:


  • HagertyRobotics
    replied
    Originally posted by dlevy View Post
    How much of the K9TankDrive have you changed? Can you share the source?

    From the original code both "left" and "right" are reset with every call to loop() so I'm not sure what you would expect by issuing left++.
    We were just saying that K9TankDrive works ok because it is using joysticks and when writing to both right and left motors, there will probably always be time when the 2nd write will be the same between two loops so a redundant write will not be needed, allowing the 1st write to go through. We didn't change any of the SDK code.

    The example that I am giving with the left++ and right++ power setting is another test we did in a new opMode. It is just an example to show that when the writes are changing each time through the loop, the first write never gets sent to the Core Legacy Module and the left motor stays at zero.

    The source code we have is for a TI Launch pad microcontroller that is acting as the Core Legacy Module. It basically just processes each incoming packet and writes it's contents over the i2c bus to the Tetrix DCMotorController. It then returns the same packet when the Android reads from the Core Legacy Module.

    Our basic problem is that later writes overwrite earlier ones to any registers on a single DCMotorController. eg. if there are three writes to different registers (motor1 power, motor2 power, mode-reset_encoder), during the first pass through the loop the reset_encoder will mask the other two. Only on the next loop will it be in the cache and not be sent. This will allow the motor2power write to be sent. The motor1power will still be masked. Only on the third write will they all be written. But this only work if none of them has changed from loop to loop. Also, writes in the Setup() method never work. None of the opMode examples have writes in the Setup() method except NxtEncoderOp and it rewrite the values again in the loop method.

    Thanks very much

    Leave a comment:


  • dlevy
    replied
    How much of the K9TankDrive have you changed? Can you share the source?

    From the original code both "left" and "right" are reset with every call to loop() so I'm not sure what you would expect by issuing left++.

    Leave a comment:

Working...
X