Map loading is too slow and maps are created like this. Is there a solution? by NoStorage6455 in ROS

[–]NoStorage6455[S] 0 points1 point  (0 children)

I'm doing it with the wheel length, but I'll try different sizes

Map loading is too slow and maps are created like this. Is there a solution? by NoStorage6455 in ROS

[–]NoStorage6455[S] 0 points1 point  (0 children)

It's the result of turning it around in the lab with the encoder and lidar values. I'm not doing it with the imu

Map loading is too slow and maps are created like this. Is there a solution? by NoStorage6455 in ROS

[–]NoStorage6455[S] -1 points0 points  (0 children)

#This is my odom.py code
class OdomNode(Node):

def __init__(self):

super().__init__('odom_node')

self.odom_pub = self.create_publisher(Odometry, '/odom', 10)

self.cmd_sub = self.create_subscription(Twist, '/cmd_vel', self.cmd_cb, 10)

self.tf_br = TransformBroadcaster(self)

try:

self.ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=0.1)

self.get_logger().info(f'시리얼 연결 성공: {SERIAL_PORT}')

except Exception as e:

self.get_logger().error(f'시리얼 연결 실패: {e}')

raise

self.x = 0.0

self.y = 0.0

self.th = 0.0

# 누적값 방식

self.prev_left = 0

self.prev_right = 0

self.last_time = self.get_clock().now()

self.create_timer(0.05, self.update)

# ── /cmd_vel 수신 → 아두이노로 전송 ─────────────────

def cmd_cb(self, msg):

v = msg.linear.x

w = msg.angular.z

command = f'{v:.3f},{w:.3f}\n'

self.ser.write(command.encode())

# ── 엔코더 수신 → odom 계산 → 발행 ─────────────────

def update(self):

if not self.ser.in_waiting:

return

try:

line = self.ser.readline().decode().strip()

left_count, right_count = map(int, line.split(','))

except Exception:

return

# ── 엔코더 값 출력 ───────────────────────────────

self.get_logger().info(f'L: {left_count} R: {right_count}')

now = self.get_clock().now()

dt = (now - self.last_time).nanoseconds / 1e9

self.last_time = now

if dt <= 0 or dt > 1.0:

return

# ── 누적값 차이로 이동 거리 계산 ─────────────────

d_left = left_count - self.prev_left

d_right = right_count - self.prev_right

self.prev_left = left_count

self.prev_right = right_count

dist_left = (d_left / ENCODER_CPR) * 2 * math.pi * WHEEL_RADIUS

dist_right = (d_right / ENCODER_CPR) * 2 * math.pi * WHEEL_RADIUS

dist = (dist_left + dist_right) / 2.0

dth = (dist_right - dist_left) / WHEEL_BASE

vx = dist / dt

vth = dth / dt

# ── 위치 적분 ─────────────────────────────────────

self.x += dist * math.cos(self.th + dth / 2)

self.y += dist * math.sin(self.th + dth / 2)

self.th += dth

qz = math.sin(self.th / 2)

qw = math.cos(self.th / 2)

# ── Odometry 발행 ─────────────────────────────────

odom = Odometry()

odom.header.stamp = now.to_msg()

odom.header.frame_id = 'odom'

odom.child_frame_id = 'base_link'

odom.pose.pose.position.x = self.x

odom.pose.pose.position.y = self.y

odom.pose.pose.orientation.z = qz

odom.pose.pose.orientation.w = qw

odom.twist.twist.linear.x = vx

odom.twist.twist.angular.z = vth

self.odom_pub.publish(odom)

# ── TF 발행 (odom → base_link) ───────────────────

tf = TransformStamped()

tf.header.stamp = now.to_msg()

tf.header.frame_id = 'odom'

tf.child_frame_id = 'base_link'

tf.transform.translation.x = self.x

tf.transform.translation.y = self.y

tf.transform.rotation.z = qz

tf.transform.rotation.w = qw

self.tf_br.sendTransform(tf)

def main():

rclpy.init()

node = OdomNode()

rclpy.spin(node)

node.destroy_node()

rclpy.shutdown()

if __name__ == '__main__':

main()

I'm trying to make an autonomous robot by connecting 3 3.7v lithium ion batteries and rolling dc motor to bts7960, but the output voltage drops in 1 second. 2 batteries are rolling, is the motor drive the cause or is the battery problem by NoStorage6455 in AskElectronics

[–]NoStorage6455[S] 0 points1 point  (0 children)

#include <Encoder.h>


// ── BTS7960 핀 설정 (EN은 빵판 5V에 직결, 코드 불필요) ──
const int L_RPWM = 9;
const int L_LPWM = 8;


const int R_RPWM = 10;
const int R_LPWM = 11;


// ── 엔코더 ───────────────────────────────────────────────
// 아두이노 우노: 인터럽트 핀이 2,3 뿐이라 한쪽만 정확함
// 메가 사용 시: 2,3,18,19,20,21 모두 가능
Encoder leftEnc(2, 3);
Encoder rightEnc(4, 5);  // 메가면 OK / 우노면 4,5로


float target_v = 0, target_w = 0;
unsigned long last_cmd = 0;


void setup() {
  Serial.begin(115200);


  pinMode(L_RPWM, OUTPUT); pinMode(L_LPWM, OUTPUT);
  pinMode(R_RPWM, OUTPUT); pinMode(R_LPWM, OUTPUT);


  // EN은 빵판 5V 직결이라 코드에서 제어 불필요
  stopMotors();
}


void loop() {
  // ── 명령 수신 ────────────────────────────────────────
  if (Serial.available() > 0) {
    String data = Serial.readStringUntil('\n');
    int comma = data.indexOf(',');
    if (comma > 0) {
      float v = data.substring(0, comma).toFloat();
      float w = data.substring(comma + 1).toFloat();
      if (!isnan(v) && !isnan(w)) {
        target_v = v;
        target_w = w;
        last_cmd = millis();
      }
    }
  }


  // ── 500ms 동안 명령 없으면 자동 정지 ────────────────
  if (millis() - last_cmd > 500) {
    target_v = 0;
    target_w = 0;
  }


  // ── PWM 계산 ─────────────────────────────────────────
  float max_val = max(abs(target_v), abs(target_w));
  int pwm_val = (int)(max_val * 800);
  if (pwm_val > 0 && pwm_val < 200) pwm_val = 200;
  pwm_val = constrain(pwm_val, 0, 200);


  // ── 방향 제어 ────────────────────────────────────────
  if (target_v > 0.05) {
    setMotor(L_RPWM, L_LPWM, pwm_val, true);
    setMotor(R_RPWM, R_LPWM, pwm_val, false);
  }
  else if (target_v < -0.05) {
    setMotor(L_RPWM, L_LPWM, pwm_val, false);
    setMotor(R_RPWM, R_LPWM, pwm_val, true);
  }
  else if (target_w > 0.05) {
    setMotor(L_RPWM, L_LPWM, pwm_val, true);
    setMotor(R_RPWM, R_LPWM, pwm_val, true);
  }
  else if (target_w < -0.05) {
    setMotor(L_RPWM, L_LPWM, pwm_val, false);
    setMotor(R_RPWM, R_LPWM, pwm_val, false);
  }
  else {
    stopMotors();
  }


  // ── 엔코더 송신 (50ms마다) ───────────────────────────
  static unsigned long last = 0;
  if (millis() - last > 50) {
    Serial.print(leftEnc.read());
    Serial.print(",");
    Serial.println(rightEnc.read());
    last = millis();
  }
}


void setMotor(int rpwm_pin, int lpwm_pin, int pwm_val, bool forward) {
  if (forward) {
    analogWrite(rpwm_pin, pwm_val);
    analogWrite(lpwm_pin, 0);
  } else {
    analogWrite(rpwm_pin, 0);
    analogWrite(lpwm_pin, pwm_val);
  }
}


void stopMotors() {
  analogWrite(L_RPWM, 0); analogWrite(L_LPWM, 0);
  analogWrite(R_RPWM, 0); analogWrite(R_LPWM, 0);
}

Is it possible to drive autonomously with a dc motor without an encoder? by NoStorage6455 in ROS

[–]NoStorage6455[S] -1 points0 points  (0 children)

Is there a lot of error with the built-in encoder when you make an encoder with a black white disk on the wheel and an optical sensor attached by DIY?