国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線)

這篇具有很好參考價值的文章主要介紹了Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

一、數(shù)據(jù)采集

1、安裝采集app

2、錄制

問題:找不到錄制數(shù)據(jù)在哪里

二、數(shù)據(jù)打包

1、準(zhǔn)備打包文件

1)kalibr_bagcreater.py

2)第三方庫utility_functions.py

2、打包

問題:/usr/bin/env: “python\r”: 沒有那個文件或目錄

三、參數(shù)標(biāo)定

1、安裝kalibr

1)安裝依賴項

2)創(chuàng)建工作空間

問題:catkin:未找到命令

3)下載及編譯

2、相機標(biāo)定

1)前期準(zhǔn)備

2)標(biāo)定

問題:kalibr_calibrate_cameras:未找到命令

3、imu標(biāo)定

1)ceres

2)依賴項

3)安裝code_utils

問題:Invoking "make -j1 -l1" failed

4)安裝imu_utils?

5)錄制imu標(biāo)定數(shù)據(jù)

6)更改文件

7)標(biāo)定

問題:RROR: cannot launch node of type [imu_utils/imu_an]: Cannot locate node of type [imu_an] in package [imu_utils]. Make sure file exists in package path and permission is set to executable (chmod +x)?

四、運行vins

1、修改參數(shù)文件

1)yaml文件

2)launch文件

2、重新編譯?

3、運行

問題:在可視化界面,有影像但是沒有軌跡(廢棄,手機導(dǎo)致的問題)

五、參考資料


今天也在痛苦面具中

系統(tǒng):Ubuntu 20.04?

ros:noetic

相機:華為手機攝像頭

大概看了一下, 大多數(shù)用手機攝像頭還是跑的離線,比直接調(diào)用usb麻煩。

一、數(shù)據(jù)采集

找了一圈,基本都是通過app來獲得所需數(shù)據(jù),這里感謝一下github上的大佬。

1、安裝采集app

app下載

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

在手機上安裝v2.0版本

2、錄制

安裝完成后打開,第一眼就是imu頁面

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

上面的三個點是設(shè)置,可以調(diào)分辨率(建議640*480)

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

下面的攝像圖案就是錄制頁面,點進去以后上面record是錄制,錄制開始后變成stop結(jié)束,第二個框是設(shè)置的分辨率,第三個框是錄制好的數(shù)據(jù)文件名??

錄制啟動的時候,原地轉(zhuǎn)幾圈,這樣初始化的結(jié)果會準(zhǔn)一點,直接前進的話可能沒有軌跡

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

?錄制完成后把數(shù)據(jù)從手機轉(zhuǎn)存到電腦上

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

問題:找不到錄制數(shù)據(jù)在哪里

我數(shù)據(jù)存的地方是 Android/data/edu.osu.pcv.marslogger/files/data

或者連接電腦后,直接在文件下面按照上面文件命名的格式搜

如果搜不到,可以嘗試開啟 開發(fā)者模式-USB調(diào)試 后尋找

?文件內(nèi)包含內(nèi)容如下:

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

movie.mp4是視頻流信息

gyro_accel.csv是imu的含有時間戳、加速度計和陀螺儀的數(shù)據(jù)

frame_timestamp.txt是視頻幀時間戳數(shù)據(jù)

二、數(shù)據(jù)打包

打包有兩種方法,一種是在ros下錄制打包,另一種是通過腳本打包,這里選擇第二種

1、準(zhǔn)備打包文件

1)kalibr_bagcreater.py

打包腳本?源碼

#!/usr/bin/env python

from __future__ import print_function
import os
import sys
import argparse
import math
import re

import rosbag
import rospy
from sensor_msgs.msg import Image
from sensor_msgs.msg import Imu

import cv2

import utility_functions

# case 1 create a rosbag from a folder as specified by the kalibr format
# https://github.com/ethz-asl/kalibr/wiki/bag-format
# structure
# dataset/cam0/TIMESTAMP.png
# dataset/camN/TIMESTAMP.png
# dataset/imu.csv

# case 2-4 create a rosbag from a video, a IMU file, and a video time file
# The video time file has the timestamp for every video frame per IMU clock.
# The saved bag will use the IMU clock to timestamp IMU and image messages.


def parse_args():
    parser = argparse.ArgumentParser(
        description='create a ROS bag containing image and imu topics '
        'from either image sequences or a video and inertial data.')
    # case 1 arguments used by the kalibr to create a rosbag from a folder
    parser.add_argument(
        '--folder',
        metavar='folder',
        nargs='?',
        help='Data folder whose content is structured as '
        'specified at\nhttps://github.com/ethz-asl/kalibr/wiki/bag-format')
    parser.add_argument('--output_bag',
                        default="output.bag",
                        help='ROS bag file %(default)s')

    # case 2 arguments to create a rosbag from a video, a IMU file,
    # and a video time file
    parser.add_argument('--video',
                        metavar='video_file',
                        nargs='?',
                        help='Video filename')
    parser.add_argument(
        '--imu',
        metavar='imu_file',
        nargs='+',
        help='Imu filename. If only one imu file is provided, '
        'then except for the optional header, '
        'each line format\n'
        'time[sec or nanosec], gx[rad/s], gy[rad/s], gz[rad/s],'
        ' ax[m/s^2], ay[m/s^2], az[m/s^2]. '
        'If gyro file and accelerometer file is provided,'
        'Each row should be: time[sec or nanosec],x,y,z'
        ' then accelerometer data will be interpolated'
        ' for gyro timestamps.')
    parser.add_argument('--first_frame_imu_time',
                        type=float,
                        default=0.0,
                        help='The time of the first video frame based on the'
                             ' Imu clock. It is used together with frame rate'
                             ' to estimate frame timestamps if the video time'
                             ' file is not provided. (default: %(default)s)',
                        required=False)
    parser.add_argument('--video_file_time_offset',
                        type=float,
                        default=0.0,
                        help='When the time file for the video is provided, '
                             'the video_file_time_offset may be added to '
                             'these timestamps.(default: %(default)s)',
                        required=False)
    parser.add_argument('--video_from_to',
                        type=float,
                        nargs=2,
                        help='Use the video frames starting from up to this'
                        ' time [s] relative to the video beginning.')
    parser.add_argument('--video_time_file',
                        default='',
                        nargs='?',
                        help='The csv file containing timestamps of every '
                        'video frames in IMU clock(default: %(default)s).'
                        ' Except for the header, each row has the '
                        'timestamp in nanosec as its first component',
                        required=False)
    parser.add_argument(
        '--downscalefactor',
        type=int,
        default=1,
        help='A video frame will be downsampled by this factor. If the resultant bag is '
        'used for photogrammetry, the original focal_length and '
        'principal_point should be half-sized, but the '
        'distortion parameters should not be changed. (default: %(default)s)',
        required=False)
    parser.add_argument(
        "--shift_secs",
        type=float,
        default=0,
        help="shift all the measurement timestamps by this amount "
        "to avoid ros time starting from 0."
        "Only for case 4, see help.")

    if len(sys.argv) < 2:
        msg = 'Example usage 1: {} --folder kalibr/format/dataset ' \
              '--output_bag awsome.bag\n'.format(sys.argv[0])

        msg += 'Example usage 1.1: {} --folder tango/android/export/ ' \
               '--imu gyro_accel.csv ' \
               '--output_bag awsome.bag\n'.format(sys.argv[0])

        msg += "dataset or export has at least one subfolder cam0 which " \
               "contains nanosecond named images"

        msg += 'Example usage 2: {} --video marslogger/ios/dataset/' \
               'IMG_2805.MOV --imu marslogger/ios/dataset/gyro_accel.csv ' \
               '--video_time_file marslogger/ios/dataset/movie_metadata.csv ' \
               '--output_bag marslogger/ios/dataset/IMG_2805.bag\n'. \
            format(sys.argv[0])

        msg += 'Example usage 3: {} --video marslogger/android/dataset/' \
               'IMG_2805.MOV --imu marslogger/android/dataset/gyro_accel.csv' \
               ' --video_time_file ' \
               'marslogger/android/dataset/frame_timestamps.txt ' \
               '--output_bag marslogger/android/dataset/IMG_2805.bag\n '. \
            format(sys.argv[0])

        msg += 'Example usage 4: {} --video advio-01/iphone/frames.MOV --imu' \
               ' advio-01/iphone/gyro.csv advio-01/iphone/accelerometer.csv' \
               ' --video_time_file advio-01/iphone/frames.csv ' \
               '--shift_secs=100 --output_bag advio-01/iphone/iphone.bag\n '.\
            format(sys.argv[0])

        msg += ('For case 2 - 4, the first column of video_time_file should be'
                ' timestamp in sec or nanosec. Also the number of entries in '
                'video_time_file excluding its header lines has to be the '
                'same as the number of frames in the video.\nOtherwise, '
                'exception will be thrown. If the video and IMU data are'
                ' captured by a smartphone, then the conventional camera '
                'frame (C) and IMU frame (S) on a smartphone approximately '
                'satisfy R_SC = [0, -1, 0; -1, 0, 0; 0, 0, -1] with '
                'p_S = R_SC * p_C')

        print(msg)
        parser.print_help()
        sys.exit(1)

    parsed = parser.parse_args()
    return parsed


def get_image_files_from_dir(input_dir):
    """Generates a list of files from the directory"""
    image_files = list()
    timestamps = list()
    if os.path.exists(input_dir):
        for path, _, files in os.walk(input_dir):
            for f in files:
                if os.path.splitext(f)[1] in ['.bmp', '.png', '.jpg', '.pnm', '.JPG']:
                    image_files.append(os.path.join(path, f))
                    timestamps.append(os.path.splitext(f)[0])
    # sort by timestamp
    sort_list = sorted(zip(timestamps, image_files))
    image_files = [time_file[1] for time_file in sort_list]
    return image_files


def get_cam_folders_from_dir(input_dir):
    """Generates a list of all folders that start with cam e.g. cam0"""
    cam_folders = list()
    if os.path.exists(input_dir):
        for rootdir, folders, _ in os.walk(input_dir):
            for folder in folders:
                if folder[0:3] == "cam":
                    cam_folders.append(os.path.join(rootdir, folder))
    return cam_folders


def get_imu_csv_files(input_dir):
    """Generates a list of all csv files that start with imu"""
    imu_files = list()
    if os.path.exists(input_dir):
        for path, _, files in os.walk(input_dir):
            for filename in files:
                if filename[0:3] == 'imu' and os.path.splitext(
                        filename)[1] == ".csv":
                    imu_files.append(os.path.join(path, filename))

    return imu_files


def load_image_to_ros_msg(filename, timestamp=None, downscalefactor=1):
    """

    :param filename:
    :param timestamp:
    :param downscalefactor: should be powers of 2.
    :return:
    """
    image_np = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
    while downscalefactor > 1:
        downscalefactor = downscalefactor // 2
        h, w = image_np.shape[:2]
        image_np = cv2.pyrDown(image_np, dstsize=(w // 2, h // 2))

    if timestamp is None:
        timestamp_nsecs = os.path.splitext(os.path.basename(filename))[0]
        timestamp = rospy.Time(secs=int(timestamp_nsecs[0:-9]),
                               nsecs=int(timestamp_nsecs[-9:]))

    rosimage = Image()
    rosimage.header.stamp = timestamp
    rosimage.height = image_np.shape[0]
    rosimage.width = image_np.shape[1]
    # only with mono8! (step = width * byteperpixel * numChannels)
    rosimage.step = rosimage.width
    rosimage.encoding = "mono8"
    rosimage.data = image_np.tostring()

    return rosimage, timestamp


def create_rosbag_for_images_in_dir(data_dir, output_bag, topic = "/cam0/image_raw", downscalefactor=1):
    """
    Find all images recursively in data_dir, and put them in a rosbag under topic.
    The timestamp for each image is determined by its index.
    It is mainly used to create a rosbag for calibrating cameras with kalibr.
    :param data_dir:
    :param output_bag: Its existing content will be overwritten.
    :param topic:
    :return:
    """
    image_files=get_image_files_from_dir(data_dir)
    print('Found #images {} under {}'.format(len(image_files), data_dir))
    bag = rosbag.Bag(output_bag, 'w')
    for index, image_filename in enumerate(image_files):
        image_msg, timestamp = load_image_to_ros_msg(image_filename, rospy.Time(index + 1, 0), downscalefactor)
        bag.write(topic, image_msg, timestamp)
    print("Saved #images {} in {} to bag {}.".format(len(image_files), data_dir, output_bag))
    bag.close()


def create_imu_message_time_string(timestamp_str, omega, alpha):
    secs, nsecs = utility_functions.parse_time(timestamp_str, 'ns')
    timestamp = rospy.Time(secs, nsecs)
    return create_imu_message(timestamp, omega, alpha), timestamp


def create_imu_message(timestamp, omega, alpha):
    rosimu = Imu()
    rosimu.header.stamp = timestamp
    rosimu.angular_velocity.x = float(omega[0])
    rosimu.angular_velocity.y = float(omega[1])
    rosimu.angular_velocity.z = float(omega[2])
    rosimu.linear_acceleration.x = float(alpha[0])
    rosimu.linear_acceleration.y = float(alpha[1])
    rosimu.linear_acceleration.z = float(alpha[2])
    return rosimu


def write_video_to_rosbag(bag,
                          video_filename,
                          video_from_to,
                          first_frame_imu_time=0.0,
                          frame_timestamps=None,
                          frame_remote_timestamps=None,
                          downscalefactor=1,
                          shift_in_time=0.0,
                          topic="/cam0/image_raw",
                          ratio=1.0):
    """
    :param bag: opened bag stream writing to
    :param video_filename:
    :param video_from_to: start and finish seconds within the video. Only frames within this range will be bagged.
    :param first_frame_imu_time: The rough timestamp of the first frame per the IMU clock.
    This value is used to estimate the video time range per the IMU clock.
    Also it is used for frame local time if frame_timestamps is empty.
    :param frame_timestamps: Frame timestamps by the host clock.
    :param frame_remote_timestamps: Frame timestamps by the remote device clock.
    :param downscalefactor: should be powers of 2
    :param shift_in_time: The time shift to apply to the resulting local (host) timestamps.
    :param ratio: ratio of output frames / input frames
    :return: rough video time range in imu clock.
    first_frame_imu_time + frame_time_in_video(0 based) ~= frame_time_in_imu.
    """
    cap = cv2.VideoCapture(video_filename)
    rate = cap.get(cv2.CAP_PROP_FPS)
    print("video frame rate {}".format(rate))

    start_id = 0
    finish_id = 1000000
    image_time_range_in_bag = list()
    framesinvideo = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    print('#Frames {} in the video {}'.format(framesinvideo, video_filename))
    if frame_timestamps is None:
        frame_timestamps = list()
    if frame_timestamps:
        if len(frame_timestamps) != framesinvideo:
            raise Exception((
                "Number of frames in the video {} disagrees with the length of"
                " the provided timestamps {}").format(framesinvideo,
                                                      len(frame_timestamps)))
    if finish_id == -1:
        finish_id = int(cap.get(cv2.CAP_PROP_FRAME_COUNT) - 1)
    else:
        finish_id = int(min(finish_id, framesinvideo - 1))
    if video_from_to and rate > 1.0:
        start_id = int(max(start_id, video_from_to[0] * rate))
        finish_id = int(min(finish_id, video_from_to[1] * rate))
    image_time_range_in_bag.append(
        max(float(start_id) / rate - 0.05, 0.0) + first_frame_imu_time +
        shift_in_time)
    image_time_range_in_bag.append(
        float(finish_id) / rate + 0.05 + first_frame_imu_time + shift_in_time)
    print('video frame index start {} finish {}'.format(start_id, finish_id))
    cap.set(cv2.CAP_PROP_POS_FRAMES,
            start_id)  # start from start_id, 0 based index
    current_id = start_id
    framecount = 0
    last_frame_remote_time = 0
    downscaletimes = 0
    while downscalefactor > 1:
        downscalefactor = downscalefactor // 2
        downscaletimes += 1
    while cap.isOpened():
        if current_id > finish_id:
            print('Exceeding finish_id %d' % finish_id +
                  ', break the video stream')
            break

        video_frame_id = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
        if video_frame_id != current_id:
            message = "Expected frame id {} and actual id in video {} " \
                      "differ.\n".format(current_id, video_frame_id)
            message += "Likely reached end of video file. Note finish_id is " \
                       "{}".format(finish_id)
            print(message)
            break

        time_frame = cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0
        time_frame_offset = time_frame + first_frame_imu_time

        _, frame = cap.read()
        if frame is None:
            print('Empty frame, break the video stream')
            break

        image_np = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        for d in range(downscaletimes):
            h, w = image_np.shape[:2]
            image_np = cv2.pyrDown(image_np, dstsize=(w // 2, h // 2))
        h, w = image_np.shape[:2]
        if w < h:
            image_np = cv2.rotate(image_np, cv2.ROTATE_90_COUNTERCLOCKWISE)
        cv2.imshow('frame', image_np)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

        if frame_timestamps:  # external
            local_time = frame_timestamps[video_frame_id]
        else:
            decimal, integer = math.modf(time_frame_offset)
            local_time = rospy.Time(secs=int(integer), nsecs=int(decimal * 1e9))
        local_time += rospy.Duration.from_sec(shift_in_time)

        remote_time = local_time
        is_dud = False
        if frame_remote_timestamps:
            remote_time = frame_remote_timestamps[video_frame_id]
            if last_frame_remote_time != 0:
                is_dud = remote_time == last_frame_remote_time
            last_frame_remote_time = remote_time
        ratiostatus = (current_id - start_id) * ratio >= framecount
        if ratiostatus and not is_dud:
            rosimage = Image()
            rosimage.header.stamp = remote_time
            rosimage.height = image_np.shape[0]
            rosimage.width = image_np.shape[1]
            rosimage.step = rosimage.width
            rosimage.encoding = "mono8"
            rosimage.data = image_np.tostring()
            bag.write(topic, rosimage, local_time)
            framecount += 1
        # else:
        #     print('Skip frame of id {}, is dud? {} ratio status? {} start_id {} framecount {}.'.format(
        #         current_id, is_dud, ratiostatus, start_id, framecount))

        current_id += 1

    cap.release()
    cv2.destroyAllWindows()
    print('Saved {} out of {} video frames as image messages to the rosbag'.
          format(framecount, framesinvideo))
    return image_time_range_in_bag


def loadtimestamps(time_file):
    """Except for the header, each row has the timestamp in nanosec
    as its first component"""
    frame_rostimes = list()

    # https://stackoverflow.com/questions/41847146/multiple-delimiters-in-single-csv-file
    with open(time_file, 'r') as stream:
        for line in stream:
            line = line.strip()
            row = re.split(' |,|[|]', line)
            if utility_functions.is_header_line(row[0]):
                continue
            secs, nsecs = utility_functions.parse_time(row[0], 'ns')
            frame_rostimes.append(rospy.Time(secs, nsecs))
    return frame_rostimes


def load_local_and_remote_times(time_file):
    """

    :param time_file: Except for the header lines, each line has the first column as the remote time in ns,
    and the last column as the local time in secs.
    :return: list of tuples (local time, remote time)
    """
    frame_rostimes = list()

    with open(time_file, 'r') as stream:
        for line in stream:
            row = re.split(' |,|[|]', line)
            if utility_functions.is_header_line(row[0]):
                continue
            secs, nsecs = utility_functions.parse_time(row[0], 'ns')
            remote_time = rospy.Time(secs, nsecs)
            local_time = rospy.Time.from_sec(float(row[-1]))
            frame_rostimes.append((local_time, remote_time))
    return frame_rostimes


def write_imufile_to_rosbag(bag, imufile, timerange=None, buffertime=5, topic="/imu0"):
    """

    :param bag: output bag stream.
    :param imufile: each line: time(ns), gx, gy, gz, ax, ay, az
    :param timerange: only write imu data within this range to the bag, in seconds.
    :param buffertime: time to pad the timerange, in seconds.
    :param topic: imu topic
    :return:
    """
    utility_functions.check_file_exists(imufile)

    with open(imufile, 'r') as stream:
        rowcount = 0
        imucount = 0
        for line in stream:
            row = re.split(' |,|[|]', line)  # note a row is a list of strings.
            if utility_functions.is_header_line(row[0]):
                continue
            imumsg, timestamp = create_imu_message_time_string(
                row[0], row[1:4], row[4:7])
            timestampinsec = timestamp.to_sec()
            rowcount += 1
            if timerange and \
                    (timestampinsec < timerange[0] - buffertime or
                     timestampinsec > timerange[1] + buffertime):
                continue
            imucount += 1
            bag.write(topic, imumsg, timestamp)
        print('Saved {} out of {} inertial messages to the rosbag'.format(
            imucount, rowcount))


def write_imufile_remotetime_to_rosbag(bag, imufile, timerange=None, buffertime=5, topic="/imu0"):
    """

    :param bag: output bag stream.
    :param imufile: each line: time(sec), gx, gy, gz, ax, ay, az, mx, my, mz, device-time(sec), and others
    :param timerange: only write imu data within this local time range to the bag, in seconds.
    :param buffertime: time to pad the timerange, in seconds.
    :param topic: imu topic
    :return:
    """
    utility_functions.check_file_exists(imufile)

    with open(imufile, 'r') as stream:
        rowcount = 0
        imucount = 0
        lastRemoteTime = rospy.Time(0, 0)
        for line in stream:
            row = re.split(' |,|[|]', line)  # note a row is a list of strings.
            if utility_functions.is_header_line(row[0]):
                continue
            local_timestamp = rospy.Time.from_sec(float(row[0]))
            remote_timestamp = rospy.Time.from_sec(float(row[10]))
            assert remote_timestamp > lastRemoteTime, \
                "remote time is not increasing in {}. Is the index of the remote time 10?".format(imufile)
            lastRemoteTime = remote_timestamp

            imumsg = create_imu_message(remote_timestamp, row[1:4], row[4:7])
            timestampinsec = local_timestamp.to_sec()
            rowcount += 1
            if timerange and \
                    (timestampinsec < timerange[0] - buffertime or
                     timestampinsec > timerange[1] + buffertime):
                continue
            imucount += 1
            bag.write(topic, imumsg, local_timestamp)

        print('Saved {} out of {} inertial messages to the rosbag'.format(
            imucount, rowcount))


def write_gyro_accel_to_rosbag(bag, imufiles, timerange=None, buffertime=5, topic="/imu0", shift_secs=0.0):
    gyro_file = imufiles[0]
    accel_file = imufiles[1]
    for filename in imufiles:
        utility_functions.check_file_exists(filename)
    time_gyro_array = utility_functions.load_advio_imu_data(gyro_file)
    time_accel_array = utility_functions.load_advio_imu_data(accel_file)
    time_imu_array = utility_functions.interpolate_imu_data(
        time_gyro_array, time_accel_array)
    bag_imu_count = 0
    for row in time_imu_array:
        timestamp = rospy.Time.from_sec(row[0]) + rospy.Duration.from_sec(shift_secs)
        imumsg = create_imu_message(timestamp, row[1:4], row[4:7])

        timestampinsec = timestamp.to_sec()
        # check below conditions when video and imu use different clocks
        # and their lengths differ much
        if timerange and \
                (timestampinsec < timerange[0] - buffertime or
                 timestampinsec > timerange[1] + buffertime):
            continue
        bag_imu_count += 1
        bag.write(topic, imumsg, timestamp)
    print('Saved {} out of {} inertial messages to the rosbag'.format(
        bag_imu_count, time_imu_array.shape[0]))


def main():
    parsed = parse_args()

    bag = rosbag.Bag(parsed.output_bag, 'w')
    videotimerange = None  # time range of video frames in IMU clock
    if parsed.video is not None:
        utility_functions.check_file_exists(parsed.video)
        print('Given video time offset {}'.format(parsed.first_frame_imu_time))
        if parsed.video_from_to:
            print('Frame time range within the video: {}'.format(parsed.video_from_to))
        first_frame_imu_time = parsed.first_frame_imu_time
        frame_timestamps = list()
        if parsed.video_time_file:
            frame_timestamps = loadtimestamps(parsed.video_time_file)
            aligned_timestamps = [time + rospy.Duration.from_sec(parsed.video_file_time_offset)
                                  for time in frame_timestamps]
            frame_timestamps = aligned_timestamps
            print('Loaded {} timestamps for frames'.format(
                len(frame_timestamps)))
            first_frame_imu_time = frame_timestamps[0].to_sec()
        videotimerange = write_video_to_rosbag(
            bag,
            parsed.video,
            parsed.video_from_to,
            first_frame_imu_time,
            frame_timestamps,
            frame_remote_timestamps=None,
            downscalefactor=parsed.downscalefactor,
            shift_in_time=parsed.shift_secs,
            topic="/cam0/image_raw")

    elif parsed.folder is not None:
        # write images
        camfolders = get_cam_folders_from_dir(parsed.folder)
        for camdir in camfolders:
            camid = os.path.basename(camdir)
            image_files = get_image_files_from_dir(camdir)
            for image_filename in image_files:
                image_msg, timestamp = load_image_to_ros_msg(image_filename)
                bag.write("/{0}/image_raw".format(camid), image_msg,
                          timestamp)
            print("Saved #images {} of {} to bag".format(
                len(image_files), camid))
    else:
        raise Exception('Invalid/Empty video file and image folder')

    # write imu data
    if (not parsed.imu) and parsed.folder is None:
        print("Neither a folder nor any imu file is provided. "
              "Rosbag will have only visual data")
    elif not parsed.imu:
        imufiles = get_imu_csv_files(parsed.folder)
        for imufile in imufiles:
            topic = os.path.splitext(os.path.basename(imufile))[0]
            with open(imufile, 'r') as stream:
                for line in stream:
                    row = re.split(' |,|[|]', line)
                    if utility_functions.is_header_line(row[0]):
                        continue
                    imumsg, timestamp = create_imu_message_time_string(
                        row[0], row[1:4], row[4:7])
                    bag.write("/{0}".format(topic), imumsg, timestamp)
    elif len(parsed.imu) == 1:
        write_imufile_to_rosbag(bag, parsed.imu[0], videotimerange, 5, "/imu0")
    else:
        write_gyro_accel_to_rosbag(bag, parsed.imu, videotimerange, 5, "/imu0", parsed.shift_secs)

    bag.close()
    print('Saved to bag file {}'.format(parsed.output_bag))


if __name__ == "__main__":
    main()
2)第三方庫utility_functions.py

補充一個第三方庫?源碼

import json
import os
import numpy as np
from numpy import genfromtxt

SECOND_TO_MILLIS = 1000
SECOND_TO_MICROS = 1000000
SECOND_TO_NANOS = 1000000000

TIME_UNIT_TO_DECIMALS = {'s': 0, "ms": 3, "us": 6, "ns": 9}


def parse_time(timestamp_str, time_unit):
    """
    convert a timestamp string to a rospy time
    if a dot is not in the string, the string is taken as an int in time_unit
    otherwise, taken as an float in secs
    :param timestamp_str:
    :return:
    """
    secs = 0
    nsecs = 0
    timestamp_str = timestamp_str.strip()
    if '.' in timestamp_str:
        if 'e' in timestamp_str:
            stamp = float(timestamp_str)
            secs = int(stamp)
            nsecs = int(round((stamp - secs) * SECOND_TO_NANOS))
        else:
            index = timestamp_str.find('.')
            if index == 0:
                nsecs = int(
                    round(float(timestamp_str[index:]) * SECOND_TO_NANOS))
            elif index == len(timestamp_str) - 1:
                secs = int(timestamp_str[:index])
            else:
                secs = int(timestamp_str[:index])
                nsecs = int(
                    round(float(timestamp_str[index:]) * SECOND_TO_NANOS))
        return secs, nsecs
    else:
        decimal_count = TIME_UNIT_TO_DECIMALS[time_unit]
        if len(timestamp_str) <= decimal_count:
            return 0, int(timestamp_str) * 10**(9 - decimal_count)
        else:
            if decimal_count == 0:
                val = float(timestamp_str)
                return int(val), int(
                    (val - int(val)) * 10**(9 - decimal_count))
            else:
                return int(timestamp_str[0:-decimal_count]),\
                       int(timestamp_str[-decimal_count:]) * 10 ** \
                       (9 - decimal_count)


def is_float(element_str):
    """check if a string represent a float. To this function, 30e5 is float,
    but 2131F or 2344f is not float"""
    try:
        float(element_str)
        return True
    except ValueError:
        return False


def is_header_line(line):
    common_header_markers = ['%', '#', '//']
    has_found = False
    for marker in common_header_markers:
        if line.startswith(marker):
            has_found = True
            break
        else:
            continue
    if not has_found:
        if line[0].isdigit():
            return False
        else:
            return True
    return has_found


def decide_delimiter(line):
    common_delimiters = [',', ' ']
    occurrences = []
    for delimiter in common_delimiters:
        occurrences.append(line.count(delimiter))
    max_occurrence = max(occurrences)
    max_pos = occurrences.index(max_occurrence)
    return common_delimiters[max_pos]


def decide_time_index_and_unit(lines, delimiter):
    """
    Time and frame number are at index 0 and 1
    Frame number may not exist
    At least two lines are required to decide if frame number exists
    Following the time or frame number is the tx ty tz and quaternions
    Unit is decided as either nanosec or sec
        depending on if decimal dot is found.
    So the unit can be wrong if timestamps in units ns or ms are provided.
    """
    if len(lines) < 2:
        raise ValueError("Not enough lines to determine time index")
    value_rows = []
    for line in lines:
        rags = line.rstrip(delimiter).split(delimiter)
        value = [float(rag) for rag in rags]
        value_rows.append(value)
    value_array = np.array(value_rows)
    delta_row = value_array[-1, :] - value_array[-2, :]
    whole_number = [value.is_integer() for value in delta_row]
    if whole_number[0]:
        if whole_number[1]:
            if delta_row[0] < delta_row[1]:  # frame id time[ns] tx[m] ty tz
                time_index = 1
                time_unit = 'ns'
                t_index = 2
            else:  # time[ns] frame id tx ty tz
                time_index = 0
                time_unit = 'ns'
                t_index = 2
        else:
            if delta_row[0] > 100:  # time[ns] tx ty tz
                time_index = 0
                time_unit = 'ns'
                t_index = 1
            else:  # frame id time[s] tx ty tz
                time_index = 1
                time_unit = 's'
                t_index = 2
    else:
        if whole_number[1]:
            # time[s] frame id tx ty tz
            time_index = 0
            time_unit = 's'
            t_index = 2
        else:
            # time[s] tx ty tz
            time_index = 0
            time_unit = 's'
            t_index = 1

    return time_index, time_unit, t_index


def normalize_quat_str(val_str_list):
    max_len = max([len(x) - x.find('.') - 1 for x in val_str_list])
    if max_len > 8:
        return val_str_list
    q4 = np.array([float(x) for x in val_str_list])
    q4_normalized = q4 / np.linalg.norm(q4)
    strlist = []
    for j in range(4):
        strlist.append("{}".format(q4_normalized[j]))
    return strlist


def read_pose_from_json(pose_json):
    """

    :param pose_json:
    :return:
    """
    with open(pose_json, 'r') as load_f:
        load_dict = json.load(load_f)
        x = float(load_dict['translation']['x'])
        y = float(load_dict['translation']['y'])
        z = float(load_dict['translation']['z'])
        q_x = float(load_dict['rotation']['i'])
        q_y = float(load_dict['rotation']['j'])
        q_z = float(load_dict['rotation']['k'])
        q_w = float(load_dict['rotation']['w'])
        pose = [x, y, z, q_x, q_y, q_z, q_w]
        return pose


def interpolate_imu_data(time_gyro_array, time_accel_array):
    """
    interpolate accelerometer data at gyro epochs
    :param time_gyro_array: each row [time in sec, gx, gy, gz]
    :param time_accel_array: each row [time in sec, ax, ay, az]
    :return: time_gyro_accel_array: each row
    [time in sec, gx, gy, gz, ax, ay, az]
    """
    a = []
    for c in range(1, 1 + 3):
        a.append(
            np.interp(time_gyro_array[:, 0], time_accel_array[:, 0],
                      time_accel_array[:, c]))
    return np.column_stack((time_gyro_array, a[0], a[1], a[2]))


def load_advio_imu_data(file_csv):
    """

    :param file_csv: each row [time in sec, x, y, z]
    :return: np array nx4
    """
    return genfromtxt(file_csv, delimiter=',', skip_header=0)


def check_file_exists(filename):
    """sanity check"""
    if not os.path.exists(filename):
        raise OSError("{} does not exist".format(filename))

2、打包

在目錄下新建一個文件夾dataset,然后把需要的東西都放進去(imu文件我重命名了一下)

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

在此目錄下打開終端進行打包

./kalibr_bagcreater.py --video movie.mp4 --imu imu.csv --video_time_file frame_timestamps.txt
問題:/usr/bin/env: “python\r”: 沒有那個文件或目錄

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

解決辦法:

①python換成python3(沒用)

打開kalibr_bagcreater.py文件,把最上面的python換成python3,保存關(guān)閉

②設(shè)置軟鏈接(沒用)

sudo ln -s /usr/bin/python3 /usr/bin/python

③用vim

# 安裝
sudo apt install vim?

# 打開文件
vim ./kalibr_bagcreater.py

直接輸入

:set ff=unix

:wq

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

然后再輸入打包命令,出現(xiàn)錄制畫面就表示一切ok,最后得到bag包

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

把錄制好的bag包放到工作空間目錄(catkin_ws)下

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

三、參數(shù)標(biāo)定

1、安裝kalibr

1)安裝依賴項
sudo apt-get install -y \
? ? git wget autoconf automake nano \
? ? libeigen3-dev libboost-all-dev libsuitesparse-dev \
? ? doxygen libopencv-dev \
? ? libpoco-dev libtbb-dev libblas-dev liblapack-dev libv4l-dev

不同的Ubuntu需要安裝不同的內(nèi)容,我安裝的20.04版本

# Ubuntu 16.04
sudo apt-get install -y python2.7-dev python-pip python-scipy \
    python-matplotlib ipython python-wxgtk3.0 python-tk python-igraph
# Ubuntu 18.04
sudo apt-get install -y python3-dev python-pip python-scipy \
    python-matplotlib ipython python-wxgtk4.0 python-tk python-igraph
# Ubuntu 20.04
sudo apt-get install -y python3-dev python3-pip python3-scipy \
    python3-matplotlib ipython3 python3-wxgtk4.0 python3-tk python3-igraph
2)創(chuàng)建工作空間
mkdir -p ~/kalibr_workspace/src
cd ~/kalibr_workspace
source /opt/ros/noetic/setup.bash
catkin init
catkin config --extend /opt/ros/noetic
catkin config --merge-devel
catkin config --cmake-args -DCMAKE_BUILD_TYPE=Release
問題:catkin:未找到命令

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

解決辦法:

sudo apt-get update
sudo apt-get install python3-catkin-tools
3)下載及編譯
cd src
git clone https://github.com/ethz-asl/kalibr.git
cd ..
catkin build -DCMAKE_BUILD_TYPE=Release?

2、相機標(biāo)定

1)前期準(zhǔn)備

在 kalibr_workspace 目錄下新建 test1 文件,并放入所需文件

①含有標(biāo)定板的bag文件

用手機錄完并打包生成rosbag文件,命名為cam0.bag

②含有標(biāo)定板信息的yaml文件,官方給了三種格式,我選擇棋盤格(checkerboard)

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

新建?checkerboard.yaml 文件并在其中填入如下內(nèi)容:

target_type: 'checkerboard' #gridtype
targetCols: 9 ? ? ? ? ? ? ? #number of internal chessboard corners
targetRows: 6 ? ? ? ? ? ? ? #number of internal chessboard corners
rowSpacingMeters: 0.025 ? ? #size of one chessboard square [m]
colSpacingMeters: 0.025 ? ? ?#size of one chessboard square [m]

保存關(guān)閉

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

2)標(biāo)定
source ~/kalibr_workspace/devel/setup.bash
kalibr_calibrate_cameras --bag ./cam0.bag --topics /cam0/image_raw --models pinhole-radtan --target checkerboard.yaml
問題:kalibr_calibrate_cameras:未找到命令

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

解決辦法:

打開 kalibr_workspace/devel/lib/kalibr ,將 kalibr_calibrate_cameras 復(fù)制到 test1 內(nèi)

然后輸入命令

./kalibr_calibrate_cameras --bag ./cam0.bag --topics?/cam0/image_raw --models pinhole-radtan --target checkerboard.yaml

成功!

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

成功后會彈出來一份標(biāo)定報告(calibration report)

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

最上面五個界面分別是 估計姿態(tài)、極差、方位角誤差、重投影誤差、異常值誤差,并且會以pdf形式在文件夾中顯示,同時還會有標(biāo)定結(jié)果的文本形式,相機標(biāo)定的配置文件

ps:重投影誤差越聚集,代表標(biāo)定情況越好

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

紅框內(nèi)的是標(biāo)定結(jié)果

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

3、imu標(biāo)定

標(biāo)定是用imu_utils實現(xiàn)的,需要一些依賴文件,所以安裝順序是ceres→code_utils→imu_utils,不能顛倒次序也不能同時安裝

1)ceres

之前已經(jīng)安裝過ceres了,所以這里就不多贅述了,具體安裝步驟可以參考?我的這篇文章?第五部分內(nèi)容

2)依賴項
sudo apt-get install libdw-dev
3)安裝code_utils
cd ~/catkin_ws/src
git clone https://github.com/gaowenliang/code_utils

在編譯前需要對文件做一點修改

打開?./code_utils/src/sumpixel_test.cpp (因為之前為了調(diào)試安裝了vim,所以默認(rèn)代碼都是用vim打開的,這里要手動選擇其他打開方式找到文本編輯器)

第二行,將引號里的內(nèi)容改成?code_utils/backward.hpp ,保存關(guān)閉

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu?

打開?./code_utils/CMakeLists.txt?

第5行,括號里改成 CMAKE_CXX_STANDARD 14 并在第7行加上 include_directories(include/code_utils) ,保存關(guān)閉

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu?

cd ..
catkin_make
問題:Invoking "make -j1 -l1" failed

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu?

解決辦法:

換一個編譯命令

catkin_make -DCATKIN_WHITELIST_PACKAGES=‘code_utils’

成功

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu?

4)安裝imu_utils?
cd ~/catkin_ws/src
git clone https://github.com/gaowenliang/imu_utils?

修改一下文件內(nèi)容

打開 ./imu_utils/CMakeLists.txt?

第6行,將括號里的內(nèi)容改成?CMAKE_CXX_STANDARD 14 ,保存關(guān)閉

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu?

cd ..
catkin_make
5)錄制imu標(biāo)定數(shù)據(jù)

開啟Record,將手機靜置至少2h(此時效果比較好,不建議太長或太短,具體時間可以自己決定)

然后把imu數(shù)據(jù)單獨打包

打開 ./kalibr_bagcreater.py

第581行,注釋掉,在下一行加上 pass ,保存關(guān)閉,這樣編譯的時候就不會因為沒有image提示了

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu?

保存關(guān)閉,輸入打包命令

./kalibr_bagcreater.py --imu imu.csv --output_bag imu.bag

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

并將其copy到 catkin_ws 目錄下

6)更改文件

進入 catkin_ws/src/imu_utils/launch 目錄下,新建 android_imu.launch 文件,并填入如下內(nèi)容

<launch>

? ? <node pkg="imu_utils" type="imu_an" name="imu_an" output="screen">
? ? ? ? <param name="imu_topic" type="string" value= "/imu0"/>
? ? ? ? <param name="imu_name" type="string" value= "HUAWEI"/>
? ? ? ? <param name="data_save_path" type="string" value= "$(find imu_utils)/"/>
? ? ? ? <param name="max_time_min" type="int" value= "120"/>
? ? ? ? <param name="max_cluster" type="int" value= "100"/>
? ? </node>

</launch>

data_sava_path 代表輸出路徑,可以根據(jù)自己的情況更改

max_time_min 代表的是錄制視頻的最長時長,如果超過120min會報錯,注意改一下

保存關(guān)閉

然后編譯一下

catkin_make
7)標(biāo)定

進入 catkin_ws 目錄下

source ~/catkin_ws/devel/setup.bash
roslaunch imu_utils android_imu.launch

# 新開一個終端
rosbag play -r 200 output.bag -s 10

?

問題:RROR: cannot launch node of type [imu_utils/imu_an]: Cannot locate node of type [imu_an] in package [imu_utils]. Make sure file exists in package path and permission is set to executable (chmod +x) (解決方法時靈時不靈)

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

解決辦法:

進入 catkin_ws/src/imu_utils/src 右鍵單擊文件 imu_an.app 打開屬性,選擇權(quán)限,發(fā)現(xiàn)是只讀,勾選 允許文件作為程序執(zhí)行

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

然后繼續(xù)編譯

source ~/catkin_ws/devel/setup.bash
roslaunch imu_utils android_imu.launch

標(biāo)定結(jié)果太差,直接用參考數(shù)值?

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

四、運行vins

1、修改參數(shù)文件

1)yaml文件

進入 /catkin_ws/src/Vins-Mono/config,新建一個名為android的文件夾,然后將euroc下的euroc_config.yaml 復(fù)制過來改名為 android_config.yaml

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

打開然后開始修改

①第6,69行,改成自己的路徑

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

②第11,12行,改分辨率,與之前錄制視頻的分辨率一致

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

③第19-22行,改相機內(nèi)參

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

數(shù)值是之前標(biāo)定過的?

④第25行,不知道imu外參,改成2(自動修正)

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

⑤第59-62行imu內(nèi)參?

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

⑥第72行,在線估計同步時差,改成1

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

保存關(guān)閉

2)launch文件

進入 /catkin_ws/src/Vins-Mono/vins_estimator/launch 對euroc.launch文件復(fù)制粘貼并重命名為android.launch

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

?修改一下路徑

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

保存關(guān)閉

2、重新編譯?

cd ~/catkin_ws
catkin_make

3、運行

打開第一個終端:

roscore

打開第二個終端:

source devel/setup.bash
roslaunch vins_estimator android.launch

打開第三個終端:

source devel/setup.bash?
roslaunch vins_estimator vins_rviz.launch

打開第四個終端:

source devel/setup.bash
rosbag play output.bag

運行成果

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

問題:在可視化界面,有影像但是沒有軌跡(廢棄,手機導(dǎo)致的問題)

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

原因:用 rosbag info 命令查一下自己錄制的內(nèi)容(第一個),和官方數(shù)據(jù)集(第二個)對比一下,發(fā)現(xiàn)imu數(shù)據(jù)沒錄進去

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu??

解決辦法:

在數(shù)據(jù)打包的時候,錄兩個bag

一個是正常錄制的(就是第一次錄的那個初始bag),命名為 movie.bag,

再錄一個imu的,根據(jù) 三.3.6) 改一下文件錄制單獨的 imu.bag ,運行命令

./kalibr_bagcreater.py --imu imu.csv --output_bag imu.bag

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

打開一個終端輸入:

roscore

打開第二個終端輸入:

rosbag record -O output.bag /cam0/image_raw /imu0

打開第三個終端輸入:

rosbag play movie.bag

等這個終端播放完畢以后繼續(xù)輸入:

rosbag play imu.bag

播放完畢后回到第二個終端結(jié)束record

ctrl+shift+C 或 ctrl+C

結(jié)束后會發(fā)現(xiàn)當(dāng)前目錄下已經(jīng)出現(xiàn)了 output.bag,這時候再查,就發(fā)現(xiàn)有兩個topic了

Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線),slam,算法,ubuntu

注意兩個topic后面的數(shù)字是不一樣的,imu 要大于 cam 要是差不多那說明你imu數(shù)據(jù)錄錯了

試了一下,還是不行,運行時會顯示?throw img, only should happen at the beginning

查了一下是初始化的問題,imu第一個數(shù)據(jù)的時間大于圖像第一個數(shù)據(jù)的時間(圖像幀有多余的)

破案了,是我手機沒有加速度計,所以讀不到完整的imu數(shù)據(jù),等有錢了一定要換一個內(nèi)置imu的手機_(:з」∠)_

五、參考資料

【VINS-MONO測試】安卓手機采集mono+imu數(shù)據(jù)

/usr/bin/env: “python3 “: 沒有那個文件或目錄

解決/usr/bin/env:python:No such file or directory

Ubuntu20.04下vins-mono調(diào)用攝像頭并跑通(D435i)

catkin:未找到命令 --解決方法

【Linux配置五】 Ubuntu18.04+kalibr標(biāo)定工具箱安裝編譯

kalibr官網(wǎng)

聯(lián)合標(biāo)定Android手機的IMU和Camera數(shù)據(jù)

解決ROS中運行l(wèi)aunch文件報錯ERROR: cannot launch node of type[xxx/xxx]:xxx的問題辦法最全匯總

rosbag 修改 topic 名稱

如何優(yōu)雅的錄制ROS的rosbag包?

VINS-Mono代碼解讀——啟動文件launch與參數(shù)配置文件yaml介紹

VINS-Mono 代碼解析二、初始化 第1部分

安卓手機 相機和IMU數(shù)據(jù)獲取標(biāo)定 在VINS-MONO運行自己的數(shù)據(jù)集(含打包方法) (非常詳細(xì)一步一步來)文章來源地址http://www.zghlxwxcb.cn/news/detail-693361.html

到了這里,關(guān)于Ubuntu20.04下vins-mono用自己數(shù)據(jù)并跑通(手機攝像頭/離線)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Ubuntu 20.04 配置 VINS-Fusion-gpu + OpenCV 4.6.0

    Ubuntu 20.04 配置 VINS-Fusion-gpu + OpenCV 4.6.0

    準(zhǔn)備工作: (1)電腦裝有 NVIDIA 顯卡 (2)安裝 ROS noetic/Installation/Ubuntu - ROS Wiki (3)安裝 cuda Ubuntu安裝cuda_GXU_Wang的博客-CSDN博客 (4)安裝 ceres 1.14.0 Ubuntu20.04安裝Ceres1.14.0_我是你de不死的bug的博客-CSDN博客 下載 opencv 源碼,選擇所需要的版本 opencv 4.6.0,相應(yīng)的擴展opencv_cont

    2024年02月12日
    瀏覽(20)
  • 在Ubuntu20.04系統(tǒng)上LIO-SAM跑KITTI數(shù)據(jù)集和自己數(shù)據(jù)集代碼修改

    在Ubuntu20.04系統(tǒng)上LIO-SAM跑KITTI數(shù)據(jù)集和自己數(shù)據(jù)集代碼修改

    參考我的另一篇文章: Ubuntu20.04下的編譯與運行LIO-SAM【問題解決】 因為liosam 要求輸入的點云每個點都有ring 信息和相對時間time信息,目前的雷達驅(qū)動基本具備這些信息,但是早期的KITTI數(shù)據(jù)集不具備,所以代碼要自己計算一下 ring和time。方法可以參考lego-loam中這部分內(nèi)容,

    2024年02月01日
    瀏覽(20)
  • 【SLAM實戰(zhàn)篇】Ubuntu 20.04版本(OpenCV版本4.5.3)對于ORB-SLAM2安裝運行,代碼編譯,自己的數(shù)據(jù)集構(gòu)造

    【SLAM實戰(zhàn)篇】Ubuntu 20.04版本(OpenCV版本4.5.3)對于ORB-SLAM2安裝運行,代碼編譯,自己的數(shù)據(jù)集構(gòu)造

    學(xué)完SLAM十四講 心血來潮想跑一下ORB-SLAM2的代碼,純新手小白,自己的踩坑經(jīng)歷進行整理: 本文章主要對ORB-SLAM2進行編譯運行。以及自己構(gòu)建數(shù)據(jù)集。 源碼github地址:https://github.com/raulmur/ORB_SLAM2 終端克隆代碼: 查看源代碼,其重要的代碼庫僅為三個文件夾: Example include s

    2024年03月13日
    瀏覽(34)
  • 將自己的Ubuntu20.04系統(tǒng)打包成鏡像(需要同一型號電腦!??!需要用作ios鏡像需要在4GB以內(nèi))

    將自己的Ubuntu20.04系統(tǒng)打包成鏡像(需要同一型號電腦!?。⌒枰米鱥os鏡像需要在4GB以內(nèi))

    1、安裝鏡像制作軟件(systemback) sudo sh -c \\\'echo \\\"deb [arch=amd64] http://mirrors.bwbot.org/ stable main\\\" /etc/apt/sources.list.d/systemback.list\\\' sudo apt-key adv --keyserver \\\'hkp://keyserver.ubuntu.com:80\\\' --recv-key 50B2C005A67B264F sudo apt-get update sudo apt-get install systemback git clone https://gitee.com/familyyao/systemback.git cd sys

    2024年02月10日
    瀏覽(22)
  • ubuntu20.04系統(tǒng)安裝使用labelme標(biāo)注數(shù)據(jù)集

    ubuntu20.04系統(tǒng)安裝使用labelme標(biāo)注數(shù)據(jù)集

    請參考:Mediapipe+VSCode+Anaconda 實時檢測手部關(guān)鍵點并保存視頻_苦瓜湯補鈣的博客-CSDN博客 1.打開終端創(chuàng)建虛擬環(huán)境 ??輸入“y”,然后回車。 ?2.激活虛擬環(huán)境,開始安裝 ?1、啟動 2、點擊【open】,選擇圖片;【Edit Polygons】---- 【Create Polygons】 ?3、可以選擇自動保存 ?

    2024年02月16日
    瀏覽(22)
  • (1)數(shù)據(jù)包嗅探和欺騙-SEED Ubuntu 20.04

    (1)數(shù)據(jù)包嗅探和欺騙-SEED Ubuntu 20.04

    網(wǎng)絡(luò)安全課程實驗一 在做的時候參考了很多網(wǎng)上主要就是CSDN上的教程。 (感覺最近還是很忙,所以等我有空想起來再來寫這個教程) (下面放一下我的實驗報告部分,里面有流程,可以做參考。 注意配合另一個文章一起看,放了命令和代碼 實驗一的命令代碼 https://blog.c

    2024年02月07日
    瀏覽(13)
  • Ubuntu20.04使用Neo4j導(dǎo)入CSV數(shù)據(jù)可視化知識圖譜

    Ubuntu20.04使用Neo4j導(dǎo)入CSV數(shù)據(jù)可視化知識圖譜

    1.安裝JDK( Ubuntu20.04 JDK11) 確認(rèn)安裝路徑為/usr/lib/jvm/java-11-openjdk-amd64/bin/java。 2 安裝Navicat查看知識庫(單機版推薦數(shù)據(jù)庫)(此步驟可忽略) 官網(wǎng)下載安裝包: 手頭的數(shù)據(jù)庫是.db格式,使用nvicat查看。 安裝好nvicat后,導(dǎo)入demo.db文件,將需要的數(shù)據(jù)轉(zhuǎn)換成csv格式。 3 安裝Neo4

    2024年04月23日
    瀏覽(25)
  • Ubuntu18.04 升級Ubuntu20.04

    Ubuntu18.04 升級Ubuntu20.04

    因項目環(huán)境需要,欲將Ubuntu18.04升級至Ubuntu20.04,參考網(wǎng)上其他小伙伴的方法,也遇到了一個問題,特此記錄一下,希望能幫助其他有同樣問題的小伙伴。 參考:第十五章 Ubuntu18.04LTS升級到20.04LTS 主要的步驟: 在執(zhí)行“do-release-upgrade”時,遇到“Failed to connect to https://changel

    2024年02月02日
    瀏覽(28)
  • Ubuntu20.04升級到Ubuntu 22.04

    Ubuntu20.04升級到Ubuntu 22.04

    執(zhí)行如下命令將Ubuntu升級到最新的版本: 升級完成后,重啟系統(tǒng) 重啟成功之后,查看系統(tǒng)的當(dāng)前版本 最新版本應(yīng)該是20.04.6,如下圖所示。 執(zhí)行如下命令開始升級 一路yes或確認(rèn)即可,下面是一些過程中的操作。 所有當(dāng)前 Ubuntu 20.04 的源列表文件將被 Ubuntu 22.04 的 jammy 源列表

    2024年02月17日
    瀏覽(26)
  • Ubuntu20.04配置

    Ubuntu20.04配置

    新創(chuàng)建的用戶沒有root權(quán)限,我們執(zhí)行以下命令給用戶sudo權(quán)限 刪除用戶及用戶所有文件(/home/username/路徑下的所有文件) 刪除用戶但保留所有用戶文件: 查詢系統(tǒng)整體磁盤使用情況: df -h 查詢指定目錄的磁盤占用情況:默認(rèn)是當(dāng)前目錄 du -h

    2024年02月04日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包