移除无用代码。

This commit is contained in:
amass 2025-03-17 14:01:30 +08:00
parent 2451467118
commit 74a38cb67a
13 changed files with 57 additions and 304 deletions

View File

@ -9,6 +9,7 @@
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/libdatachannel-0.22.5",
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/include",
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/LeakTracer/include",
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/opencv-4.11.0/include/opencv4",
"build/_deps/kylin-src"
],
"defines": [],

View File

@ -1,140 +0,0 @@
/*
* @Author: Alfred Xiang Wu
* @Date: 2022-11-20 22:18:49
* @Breif:
* @Last Modified by: Alfred Xiang Wu
* @Last Modified time: 2023-09-19 22:32:56
*/
#ifndef _DS_PEDESTRIAN_MOT_HISI_H_
#define _DS_PEDESTRIAN_MOT_HISI_H_
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <stdint.h> // int64_t
#define RW_LICENSE_CHECK
#if defined _WINDOWS && !(defined _LIB)
#ifdef DS_PEDESTRIAN_MOT_HISI_EXPORTS
#define DS_PEDESTRIAN_MOT_HISI_API __declspec(dllexport)
#else
#define DS_PEDESTRIAN_MOT_HISI_API __declspec(dllimport)
#endif
#else
#define DS_PEDESTRIAN_MOT_HISI_API
#endif
typedef void* DS_PEDESTRIAN_MOT_HANDLE;
// for detection
typedef struct PedestrianRect {
float xmin;
float ymin;
float xmax;
float ymax;
float score;
int label;
} PedestrianRect;
// for tracking
typedef struct io_MEASURE {
std::vector<float> state; // bbox: xmin, ymin, xmax, ymax
int frame; // frame id
float conf; // confidence for bbox
} io_MEASURE;
typedef struct io_person {
io_MEASURE head; // head bbox (don't use head bbox for any analysis.)
io_MEASURE body; // body bbox
int tracked = 0; // track state
float quality_score = 0.0; // quality scores
} io_person;
typedef struct io_TrackData {
int track_id; // track id
int track_state; // track state: 0 pre-track; +1 confirmed; -1 hibernate; -2 remove;
io_person prediction; // bbox at the current frame (If track_state != 1, prediction is empty.)
} io_TrackData;
#if defined(__cplusplus)
extern "C"
{
#endif
#ifdef RW_LICENSE_CHECK
DS_PEDESTRIAN_MOT_HISI_API void ds_pedestrian_hisi_set_lic_path(const char *path);
#endif // RW_LICENSE_CHECK
/**
* The function is used to initialize the pedestrian detection and tracking handle.
*
* @param handle the handle
* @param det_model_path The path to the pedestrian detection model.
* @param reid_model_path the path of the pedestrian tracking reid model
* @param width width of the input image
* @param height the height of the input image
* @param channels the number of channels of the input image, It must be 3 channels.
*
* @return A handle for the pedestrian detection and tracking.
*/
DS_PEDESTRIAN_MOT_HISI_API int ds_pedestrian_hisi_init(
DS_PEDESTRIAN_MOT_HANDLE* handle,
char* det_model_path,
char* reid_model_path,
const int width,
const int height,
const int channels);
/**
* The function is the interface function for pedestrian detection.
*
* @param handle The handle.
* @param bboxes the output of the pedestrian detection model, which is a vector of PedestrianRect.
*
* @return the bounding boxes of the detected pedestrians.
*/
DS_PEDESTRIAN_MOT_HISI_API int ds_pedestrian_det_hisi(
DS_PEDESTRIAN_MOT_HANDLE handle,
unsigned char* img,
std::vector<PedestrianRect> &bboxes);
/**
* The function is the interface function for pedestrian tracking.
*
* @param handle The handle.
* @param nframe the frame number of the current frame
* @param det_bboxes the detection results of the current frame, which is a vector of PedestrianRect.
* @param tracks the output of the tracking results, which is a vector of io_TrackData.
*
* @return the number of tracks.
*/
DS_PEDESTRIAN_MOT_HISI_API int ds_pedestrian_track_hisi(
DS_PEDESTRIAN_MOT_HANDLE handle,
unsigned char* img,
const int nframe,
std::vector<PedestrianRect> det_bboxes,
std::vector<io_TrackData> &tracks);
/**
* It releases the resources allocated in the initialization function.
*
* @param handle The handle.
*
* @return The handle.
*/
DS_PEDESTRIAN_MOT_HISI_API int ds_pedestrian_hisi_release(
DS_PEDESTRIAN_MOT_HANDLE *handle);
#if defined(__cplusplus)
}
#endif
#endif // _DS_PEDESTRIAN_MOT_HISI_H_

View File

@ -9,6 +9,7 @@ option(CROSS_BUILD "build for embeded product." ON)
if(CROSS_BUILD)
set(Libraries_ROOT /opt/aarch64-v01c01-linux-gnu-gcc/lib)
set(OpenCV_DIR ${Libraries_ROOT}/opencv-4.11.0/lib/cmake/opencv4)
set(OPENSSL_ROOT_DIR ${Libraries_ROOT}/openssl-3.4.1)
set(OPENSSL_LIBRARY_DIRS ${OPENSSL_ROOT_DIR}/libs)
set(SCTP_ROOT ${Libraries_ROOT}/usrsctp-0.9.5.0)

View File

@ -1,23 +1,19 @@
find_package(OpenSSL REQUIRED)
find_package(OpenCV REQUIRED)
add_executable(PassengerStatistics main.cpp
DetectAlgorithm.h DetectAlgorithm.cpp
ImageUtilities.h ImageUtilities.cpp
RtspServer.h RtspServer.cpp
VideoInput.h VideoInput.cpp
)
target_include_directories(PassengerStatistics
PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/libopencv/include
PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/rw_mpp/include
PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/ds_pedestrian_mot_hisi/include
PRIVATE ${ZLMediaKit_INCLUDE_DIR}
)
target_link_directories(PassengerStatistics
PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/libopencv/libs
PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/rw_mpp/lib
PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/ds_pedestrian_mot_hisi/libs
PRIVATE ${ZLMediaKit_LIBRARY_DIRS}
PRIVATE ${OPENSSL_LIBRARY_DIRS}
)
@ -27,10 +23,7 @@ target_link_libraries(PassengerStatistics
PRIVATE OpenSSL::SSL
PRIVATE OpenSSL::Crypto
PRIVATE rw_mpp
PRIVATE ds_pedestrian_mot_Hi3516DV500
PRIVATE mk_api
PRIVATE opencv_core
PRIVATE opencv_imgcodecs
PRIVATE opencv_imgproc
PRIVATE ${OpenCV_LIBS}
PRIVATE ${SCTP_LIBRARIES}
)

View File

@ -1,75 +0,0 @@
#include "DetectAlgorithm.h"
#include "Core/Logger.h"
#include "ImageUtilities.h"
#include <ds_pedestrian_mot_hisi.h>
#include <filesystem>
#include <thread>
class DetectAlgorithmPrivate {
public:
std::vector<io_TrackData> tracks;
};
DetectAlgorithm::DetectAlgorithm() : m_d(new DetectAlgorithmPrivate()) {
}
DetectAlgorithm::~DetectAlgorithm() {
if (m_handle != nullptr) {
ds_pedestrian_hisi_release(&m_handle);
}
if (m_d != nullptr) {
delete m_d;
}
}
DetectAlgorithm::Result DetectAlgorithm::detect(const uint8_t *nv21ImageData, uint64_t frameIndex) {
DetectAlgorithm::Result ret;
if (m_handle == nullptr) { // 一定得在这里执行
initialize();
}
ImageUtilities::NV21ToBGR24(nv21ImageData, m_rgbImageBuffer.data(), DetectWidth, DetectHeight);
std::vector<PedestrianRect> pedestrians;
ds_pedestrian_det_hisi(m_handle, m_rgbImageBuffer.data(), pedestrians);
ds_pedestrian_track_hisi(m_handle, m_rgbImageBuffer.data(), frameIndex, pedestrians, m_d->tracks);
LOG(info) << "frame: " << frameIndex << ", pedestrians: " << pedestrians.size()
<< ", tracks: " << m_d->tracks.size();
for (auto iterator = m_d->tracks.cbegin(); iterator != m_d->tracks.cend();) {
if (iterator->track_state == TrackState::Remove) {
ret.leaveTrackers.push_back(iterator->track_id);
iterator = m_d->tracks.erase(iterator);
continue;
} else if (iterator->track_state == TrackState::Confirmed) {
LOG(info) << iterator->prediction.body.conf << " " << iterator->prediction.head.conf;
LOG(info) << iterator->prediction.body.state[0] << " " << iterator->prediction.body.state[1] << " "
<< iterator->prediction.body.state[2] << " " << iterator->prediction.body.state[3];
LOG(info) << iterator->prediction.head.state[0] << " " << iterator->prediction.head.state[1] << " "
<< iterator->prediction.head.state[2] << " " << iterator->prediction.head.state[3];
}
++iterator;
}
return ret;
}
void DetectAlgorithm::initialize() {
constexpr auto licensePath = "/kdata/net.lic";
bool licenseExisted = std::filesystem::exists(licensePath);
if (licenseExisted && std::filesystem::file_size(licensePath) <= 0) {
LOG(warning) << "license " << licensePath << " content is empty, remove it.";
std::filesystem::remove(licensePath);
licenseExisted = false;
}
ds_pedestrian_hisi_set_lic_path("/kdata");
int status = ds_pedestrian_hisi_init(&m_handle, "/system/models/ds_mot_m0_2000.bin",
"/system/models/ds_mot_m1_2000.bin", DetectWidth, DetectHeight, 3);
if (status != 0) {
LOG(error) << "ds_pedestrian_hisi_init() failed, status: " << status;
m_handle = nullptr;
} else {
LOG(info) << "detect algorithm initialization successfully.";
}
if (!licenseExisted && std::filesystem::exists(licensePath)) {
system("sync");
}
}

View File

@ -1,35 +0,0 @@
#ifndef __DETECTALGORITHM_H__
#define __DETECTALGORITHM_H__
#include <array>
#include <cstdint>
#include <vector>
class DetectAlgorithmPrivate;
class DetectAlgorithm {
public:
enum TrackState : int {
Remove = -2,
Hibernate = -1,
PreTrack = 0,
Confirmed = 1,
};
class Result {
public:
std::vector<int> leaveTrackers;
};
constexpr static uint32_t DetectWidth = 576;
constexpr static uint32_t DetectHeight = 320;
DetectAlgorithm();
~DetectAlgorithm();
Result detect(const uint8_t *nv21ImageData, uint64_t frameIndex);
void initialize();
private:
DetectAlgorithmPrivate *m_d = nullptr;
void *m_handle = nullptr;
std::array<uint8_t, DetectWidth * DetectHeight * 3> m_rgbImageBuffer;
};
#endif // __DETECTALGORITHM_H__

View File

@ -9,6 +9,13 @@ class RtspServer {
public:
RtspServer();
~RtspServer();
/**
* @brief ffplay.exe rtsp://192.168.3.11/live/video
*
* @param data
* @param size
*/
void push(const uint8_t *data, uint32_t size);
private:

View File

@ -1,6 +1,5 @@
#include "VideoInput.h"
#include "Core/Logger.h"
#include "DetectAlgorithm.h"
#include "rw_mpp_api.h"
#include <chrono>
@ -11,7 +10,6 @@ public:
int32_t encodeChannel = -1;
int32_t scaleChannel = -1;
S_vdec_config decoderConfig;
std::shared_ptr<DetectAlgorithm> m_detector;
};
VideoInput::VideoInput(int32_t width, int32_t height) : m_d(new VideoInputPrivate()), m_width(width), m_height(height) {
@ -19,8 +17,6 @@ VideoInput::VideoInput(int32_t width, int32_t height) : m_d(new VideoInputPrivat
if (status != 0) {
LOG(error) << "rw_mpp__vdec_init() failed, status: " << status;
}
m_d->m_detector = std::make_shared<DetectAlgorithm>();
}
VideoInput::~VideoInput() {
@ -108,7 +104,7 @@ bool VideoInput::startEncode() {
}
m_d->scaleChannel = 0;
S_vscale_cfg scaleConfig = {2960, 1664, DetectAlgorithm::DetectWidth, DetectAlgorithm::DetectHeight};
S_vscale_cfg scaleConfig = {2960, 1664, 1280, 720};
status = rw_mpp__vscale_start(m_d->scaleChannel, &scaleConfig);
if (status != 0) {
LOG(error) << "rw_mpp__vscale_start() failed, status: " << status;
@ -144,7 +140,6 @@ void VideoInput::setPacketHandler(const PacketHandler &hanlder) {
}
void VideoInputPrivate::processImage(S_mpp_img &image, S_mpp_img &detectImage, uint64_t frameIndex) {
m_detector->detect(detectImage.nv21, frameIndex);
}
void VideoInputPrivate::processFrame(S_mpp_img &image) {

View File

@ -29,12 +29,12 @@ int main(int argc, char const *argv[]) {
auto video = std::make_shared<VideoInput>(2592, 1536);
video->setPacketHandler([&](const uint8_t *data, uint32_t size) {
ofs->write(reinterpret_cast<const char *>(data), size);
// ofs->write(reinterpret_cast<const char *>(data), size);
// pusher->push(data, size);
rtsp->push(data, size);
});
// video->start();
video->startFileInput("/data/sdcard/HM1.264", 1280, 720);
video->start();
// video->startFileInput("/data/sdcard/HM1.264", 1280, 720);
video->startEncode();
boost::asio::signal_set signals(*ioContext->ioContext(), SIGINT);
signals.async_wait([&](boost::system::error_code const &, int signal) {
@ -44,7 +44,7 @@ int main(int argc, char const *argv[]) {
ioContext->ioContext()->stop();
});
ioContext->run(false);
ioContext->run(true);
} catch (const boost::exception &e) {
LOG(error) << "error";
} catch (const std::exception &e) {
@ -52,5 +52,6 @@ int main(int argc, char const *argv[]) {
}
rw_mpp__finalize();
LOG(info) << "app exit.";
return 0;
}

View File

@ -1,6 +1,16 @@
#!/bin/bash
# Host danki
# HostName 192.168.3.11
# User root
# IdentityFile ~/.ssh/ssh_host_rsa_key_ok
# Port 22
# KexAlgorithms +diffie-hellman-group1-sha1
# HostkeyAlgorithms +ssh-dss,ssh-rsa
# PubkeyAcceptedKeyTypes +ssh-dss,ssh-rsa
# Ciphers +aes128-cbc%
cross_compile=true
TARGET_IP="192.168.3.220"
TARGET_PATH="/data/sdcard/PassengerStatistics"
base_path=$(pwd)
libraries_root="/opt/Libraries"
@ -29,9 +39,6 @@ function cmake_scan() {
}
function build() {
if [ -n "$1" ]; then
TARGET_IP=$1
fi
if [ ! -f "${build_path}/CMakeCache.txt" ]; then
cmake_scan
fi
@ -51,45 +58,43 @@ function build() {
}
function init() {
if [ -n "$1" ]; then
TARGET_IP=$1
fi
echo "deploy libs to target $TARGET_IP..."
BOOST_LIBDIR=/opt/aarch64-v01c01-linux-gnu-gcc/lib/boost_1_84_0/lib
chmod 600 resources/ssh_host_rsa_key_ok
ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "mount -o remount rw /;mount -o remount rw /system/"
echo "put ${base_path}/resources/authorized_keys /system/.ssh" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "deploy libs to target ..."
BOOST_LIBDIR=/opt/aarch64-v01c01-linux-gnu-gcc/lib/boost_1_87_0/lib
ssh danki "mount -o remount rw /;mount -o remount rw /system/"
ssh danki "mkdir -p /data/sdcard/PassengerStatistics/lib"
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/gdb-10.2/bin/gdbserver /system/bin" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "mkdir -p /data/sdcard/PassengerStatistics/lib"
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/lib/libmk_api.so /data/sdcard/PassengerStatistics/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/LeakTracer/libleaktracer.so /data/sdcard/PassengerStatistics/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
# echo "put ${BOOST_LIBDIR}/libboost_date_time* /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_regex.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_log_setup.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_log.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_atomic.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_chrono.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_container.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_filesystem.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_thread.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_url.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_json.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_program_options.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put 3rdparty/rw_mpp/lib/librw_mpp.so /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put 3rdparty/ds_pedestrian_mot_hisi/libs/libds_pedestrian_mot_Hi3516DV500.so /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/openssl-3.4.1/lib/libssl.so.3 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/openssl-3.4.1/lib/libcrypto.so.3 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/lib/libmk_api.so /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/opencv-4.11.0/lib/libopencv_world.so.4.11.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/usrsctp-0.9.5.0/lib/libusrsctp.so.2.0.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
# echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/LeakTracer/libleaktracer.so /data/sdcard/PassengerStatistics/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
# echo "put ${BOOST_LIBDIR}/libboost_regex.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_log_setup.so.1.87.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put ${BOOST_LIBDIR}/libboost_log.so.1.87.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put ${BOOST_LIBDIR}/libboost_atomic.so.1.87.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put ${BOOST_LIBDIR}/libboost_chrono.so.1.87.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put ${BOOST_LIBDIR}/libboost_system.so.1.87.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put ${BOOST_LIBDIR}/libboost_filesystem.so.1.87.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
echo "put ${BOOST_LIBDIR}/libboost_thread.so.1.87.0 /data/sdcard/PassengerStatistics/lib" | sftp danki
# echo "put ${BOOST_LIBDIR}/libboost_url.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
# echo "put ${BOOST_LIBDIR}/libboost_json.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
# echo "put ${BOOST_LIBDIR}/libboost_program_options.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "echo 'mount -o remount rw /' >> /etc/profile"
ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "echo 'mount -o remount rw /system/' >> /etc/profile"
ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "echo 'export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/system/lib:/data/sdcard/PassengerStatistics/lib' >> /etc/profile"
# ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "echo 'mount -o remount rw /' >> /etc/profile"
# ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "echo 'mount -o remount rw /system/' >> /etc/profile"
}
function deploy() {
if [ -n "$1" ]; then
TARGET_IP=$1
fi
echo "deploy to target $TARGET_IP, path: ${TARGET_PATH} ..."
echo "put ${build_path}/Main/PassengerStatistics ${TARGET_PATH}" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${build_path}/Tools/VideoRecoder/VideoRecoder ${TARGET_PATH}" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${build_path}/Tools/LeakTracer/LeakTracer ${TARGET_PATH}" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "sync"
echo "deploy to target, path: ${TARGET_PATH} ..."
echo "put ${build_path}/Main/PassengerStatistics ${TARGET_PATH}" | sftp danki
echo "put ${build_path}/Tools/LeakTracer/LeakTracer ${TARGET_PATH}" | sftp danki
ssh danki "sync"
}