Negative position?

Questions about using encoders with the Roboclaw product line
rwschumann
Posts: 8
Joined: Wed Jun 20, 2018 7:39 am

Negative position?

Postby rwschumann » Wed Jun 20, 2018 8:20 am

I want to use the position commands to control how much movement occurs.

I was planning on using the zero encoder position as my mid point (eg moving backwards would result in a negative encoder count).

When using distance commands and such the encoder behaves as I would expect going positive and negative as I issue distance commands.

However the position command appears to NOT deal with negative positions at all?

Please confirm.

If true do I need to set an artificial mid-point and can I use the set encoder command?

User avatar
Basicmicro Support
Posts: 1077
Joined: Thu Feb 26, 2015 9:45 pm

Re: Negative position?

Postby Basicmicro Support » Thu Jun 21, 2018 10:06 am

You need to use a signed variable when you read the position value. It will convert the unsigned 32bit value into a signed value properly. It is written this way so you can use it either signed of unsigned positions.

rwschumann
Posts: 8
Joined: Wed Jun 20, 2018 7:39 am

Re: Negative position?

Postby rwschumann » Thu Jun 21, 2018 1:24 pm

Correct. When I read the position I am able to accurately see it go negative.

However if I use a position command, such as

66 - Buffered Drive M2 with signed Speed, Accel, Deccel and Position
Move M2 position from the current position to the specified new position and hold the new
position. Accel sets the acceleration value and deccel the decceleration value. QSpeed sets the
speed in quadrature pulses the motor will run at after acceleration and before decceleration.

it does NOT accept a negative value. So while I can read that I have gone negative I cannot actually send the device there.

Basically it comes down to the core problem from this whole thread which is that the handling of the "position" and encoder value is muddled. Sometimes treated as signed and sometimes not.

User avatar
Basicmicro Support
Posts: 1077
Joined: Thu Feb 26, 2015 9:45 pm

Re: Negative position?

Postby Basicmicro Support » Thu Jun 21, 2018 4:52 pm

Please post your code.

rwschumann
Posts: 8
Joined: Wed Jun 20, 2018 7:39 am

Re: Negative position?

Postby rwschumann » Fri Jun 22, 2018 1:07 pm

I have included two files, below
1) Arduino code which executes 'forward' and 'backward' distance and position commands
2) Log file showing results of the calls.

In the log file you can see that:
a) When doing a forward call (either distance or position) it all works fine.
b) When doing a position backward call it works fine until you do one which would bring it to a negative position. In this case it does the position towards '0'. then stops. (You can see this in the duration time and end position.
c) When doing a distance backward call which would go negative it basically runs forever as it is trying to get to some huge count position.

So the position command clearly recognized this as a negative number, or overflow, or something and stops.
THanks,
Rob


Code: Select all

//See BareMinimum example for a list of library functions

//Includes required to use Roboclaw library
#include <SoftwareSerial.h>
#include "RoboClaw.h"

//See limitations of Arduino SoftwareSerial
//SoftwareSerial serial(10,11);   
RoboClaw roboclaw(&Serial2,10000);


#define address 0x80
#define MOTOR_RELAY 12
#define POWER_RELAY 11


//This is the first function arduino runs on reset/power up
void setup() {
  pinMode(MOTOR_RELAY, OUTPUT);
  digitalWrite(MOTOR_RELAY, LOW);
  pinMode(POWER_RELAY, OUTPUT);
  digitalWrite(POWER_RELAY, LOW);

  delay(500);
 
  //Open Serial and roboclaw at 38400bps
  Serial.begin(57600);
  roboclaw.begin(38400);

  // Set our encoder count to zero
  roboclaw.SetEncM2(address, 0x0);

  Serial.println("Starting...");
}


void loop() {
static int32_t cur_pos = 0;

   Serial.printf("cmd: ");
   while(Serial.available() == 0) {
    delay(50);
   }
  char chr = Serial.read();
  Serial.printf("%c\n\r",chr);
  boolean active=false;
  boolean distance = false;
  int32_t mvmt = 0;
  switch(chr) {
    case 'b':
      mvmt = -1500;
      active = true;
      break;
    case 'B':
      mvmt = -1500;
      active = true;
      distance = true;
      break;
    case 'f':
      mvmt = 1000;
      active = true;
      break;
    case 'F':
      mvmt = 1000;
      active = true;
      distance = true;
      break;   
    default:
      Serial.printf("Commands are 'b' or 'f' for position or 'B' or 'F' for distance command\n\r");
      break;
  }
  if (active) {
      uint8_t status;
      bool valid;
      uint32_t rc_pos;
      rc_pos = roboclaw.ReadEncM2(address, &status, &valid);
      cur_pos = rc_pos+mvmt; 
      Serial.printf("moving to position: %ld  from position: %ld\n\r",cur_pos,(int32_t)rc_pos);
      if (distance == false)
        roboclaw.SpeedAccelDeccelPositionM2(address,10000,7000,3000,(uint32_t)cur_pos,1);
      else
        roboclaw.SpeedAccelDistanceM2(address,10000,3000,(uint32_t)mvmt,1);     
      uint8_t depth1, depth2;
      unsigned long start_time = millis();
      do {
         roboclaw.ReadBuffers(address, &depth1, &depth2);
         delay(50);
      } while(depth2 != 0x80);

      roboclaw.ReadBuffers(address, &depth1, &depth2);     
      rc_pos = roboclaw.ReadEncM2(address, &status, &valid);
      Serial.printf("Finished, elapsed time: %ld(ms), ending position: %lu(unsigned)  %ld(signed)\n\r",millis()-start_time, rc_pos,(int32_t)rc_pos);
  };
}



Connecting to COM14...
Connected.

Started with speed: 38400
Starting...
cmd: f
moving to position: 2223 from position: 1223
Finished, elapsed time: 909(ms), ending position: 1973(unsigned) 1973(signed)
cmd: f
moving to position: 3149 from position: 2149
Finished, elapsed time: 962(ms), ending position: 2945(unsigned) 2945(signed)
cmd: b
moving to position: 1503 from position: 3003
Finished, elapsed time: 1173(ms), ending position: 1736(unsigned) 1736(signed)
cmd: b
moving to position: 99 from position: 1599
Finished, elapsed time: 1071(ms), ending position: 295(unsigned) 295(signed)
cmd: b
moving to position: -1373 from position: 127
Finished, elapsed time: 326(ms), ending position: 84(unsigned) 84(signed)
cmd: b
moving to position: -1416 from position: 84
Finished, elapsed time: 61(ms), ending position: 84(unsigned) 84(signed)
cmd: F
moving to position: 1021 from position: 21
Finished, elapsed time: 748(ms), ending position: 1153(unsigned) 1153(signed)
cmd: b
moving to position: 738 from position: 2238
Finished, elapsed time: 1174(ms), ending position: 1008(unsigned) 1008(signed)
cmd: B
moving to position: -753 from position: 747

Connection closed.

User avatar
Basicmicro Support
Posts: 1077
Joined: Thu Feb 26, 2015 9:45 pm

Re: Negative position?

Postby Basicmicro Support » Mon Jun 25, 2018 10:43 am

Here is a modification of the Position example included in our Roboclaw library.

Code: Select all

//See BareMinimum example for a list of library functions

//Includes required to use Roboclaw library
#include <SoftwareSerial.h>
#include "RoboClaw.h"

//See limitations of Arduino SoftwareSerial
//SoftwareSerial serial(10,11);   
RoboClaw roboclaw(&Serial1,10000);

#define address 0x80

//Display Encoder and Speed for Motor 1
void displayspeed(void)
{
  uint8_t status1,status2;
  bool valid1,valid2;
  int32_t enc1 = roboclaw.ReadEncM2(address, &status1, &valid1);
  int32_t speed1 = roboclaw.ReadSpeedM2(address, &status2, &valid2);
 
  Serial.print("Encoder1:");
  if(valid1){
    Serial.print(enc1,DEC);
    Serial.print(" ");
    Serial.print(status1,HEX);
    Serial.print(" ");
  }
  else{
    Serial.print("failed ");
  }

  Serial.print("Speed1:");
  if(valid2){
    Serial.print(speed1,DEC);
    Serial.print(" ");
  }
  else{
    Serial.print("failed ");
  }
 
  Serial.println();
}

//This is the first function arduino runs on reset/power up
void setup() {
  //Open Serial and roboclaw at 38400bps
  Serial.begin(57600);
  roboclaw.begin(38400);
 
  Serial.println("Starting...");
}

void loop() {
  roboclaw.SpeedAccelDeccelPositionM2(address,0,4000,0,4000,1);
  roboclaw.SpeedAccelDeccelPositionM2(address,0,4000,0,-4000,0);
  long last = millis();
  while(millis()-last<5000){
    displayspeed();
    delay(50);
  }
}


Note you must have set the Min and Max position range to atleast -4000 to 4000(I set mine to -5000 to 5000). Also make sure everything works in IonStudio and you save your settings before testing this example.


Return to “Velocity and Position Control”

Who is online

Users browsing this forum: No registered users and 3 guests

cron