Skip to content

Commit

Permalink
progress nav API and MVSIM interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jlblancoc committed Jun 14, 2021
1 parent 91c618c commit c30df8b
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 53 deletions.
124 changes: 99 additions & 25 deletions apps/selfdriving-simulator-gui/selfdriving-simulator-gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <mrpt/math/TLine3D.h>
#include <mrpt/math/TObject3D.h>
#include <mrpt/opengl/CDisk.h>
#include <mrpt/system/CRateTimer.h>
#include <mrpt/system/os.h> // plugins
#include <mrpt/version.h>
#include <mvsim/Comms/Server.h>
Expand All @@ -23,6 +24,7 @@
#include <selfdriving/algos/WaypointSequencer.h>
#include <selfdriving/algos/viz.h>
#include <selfdriving/data/Waypoints.h>
#include <selfdriving/interfaces/MVSIM_VehicleInterface.h>

#include <rapidxml_utils.hpp>
#include <thread>
Expand Down Expand Up @@ -79,14 +81,11 @@ void commonLaunchServer()

server->start();
}
struct TThreadParams

struct CommonThreadParams
{
std::mutex closingMtx;

std::shared_ptr<mvsim::World> world;

TThreadParams() = default;

bool isClosing()
{
closingMtx.lock();
Expand All @@ -105,18 +104,27 @@ struct TThreadParams
bool closing_ = false;
};

static void mvsim_server_thread_update_GUI(TThreadParams& tp);
struct GUI_ThreadParams : public CommonThreadParams
{
std::shared_ptr<mvsim::World> world;
};

static void mvsim_server_thread_update_GUI(GUI_ThreadParams& tp);
mvsim::World::TGUIKeyEvent gui_key_events;
std::mutex gui_key_events_mtx;
std::string msg2gui;

// ======= Self Drive status ===================
struct SelfDrivingThreadParams : public CommonThreadParams
{
};

struct SelfDrivingStatus
{
SelfDrivingStatus() = default;

selfdriving::ObstacleSource::Ptr obstacles;
selfdriving::CostEvaluatorCostMap::Ptr costMap;
// selfdriving::ObstacleSource::Ptr obstacles;
// selfdriving::CostEvaluatorCostMap::Ptr costMap;

selfdriving::PlannerInput pi;
selfdriving::TPS_RRTstar planner;
Expand All @@ -127,24 +135,65 @@ struct SelfDrivingStatus
selfdriving::WaypointSequence waypts;
selfdriving::WaypointStatusSequence wayptsStatus;
selfdriving::WaypointSequencer navigator;

std::shared_ptr<selfdriving::MVSIM_VehicleInterface> mvsimVehicleInterface;

SelfDrivingThreadParams sdThreadParams;
std::thread selfDrivingThread;
};

SelfDrivingStatus sd;

static void selfdriving_run_thread(SelfDrivingThreadParams& params);

// ======= End Self Drive status ===================

void prepare_selfdriving()
void prepare_selfdriving(mvsim::World& world)
{
// initialize the WaypointSequencer
// --------------------------------------------------------
// sd.navigator.config_.multitarget_look_ahead = 2;

// Load PTGs:
{
mrpt::config::CConfigFile cfg(arg_ptgs_file.getValue());
sd.navigator.config_.ptgs.initFromConfigFile(
cfg, arg_config_file_section.getValue());
}

// Obstacle source:
auto obsPts = mrpt::maps::CSimplePointsMap::Create();

world.runVisitorOnWorldElements([&](mvsim::WorldElementBase& we) {
auto grid = dynamic_cast<mvsim::OccupancyGridMap*>(&we);
if (!grid) return;
grid->getOccGrid().getAsPointCloud(*obsPts);
});

sd.navigator.config_.obstacleSource =
selfdriving::ObstacleSource::FromStaticPointcloud(obsPts);

// Vehicle interface:
sd.mvsimVehicleInterface =
std::make_shared<selfdriving::MVSIM_VehicleInterface>();
sd.mvsimVehicleInterface->connect();

sd.navigator.config_.vehicleMotionInterface = sd.mvsimVehicleInterface;

// all mandaroty fields filled in now:
sd.navigator.initialize();

sd.selfDrivingThread =
std::thread(&selfdriving_run_thread, std::ref(sd.sdThreadParams));

// Load example/test waypoints?
// --------------------------------------------------------
if (arg_waypoints_yaml_file.isSet())
{
sd.waypts = selfdriving::WaypointSequence::FromYAML(
mrpt::containers::yaml::FromFile(
arg_waypoints_yaml_file.getValue()));
}

// initialize the WaypointSequencer
// sd.navigator.config_.multitarget_look_ahead = 2;

sd.navigator.initialize();
}

int launchSimulation()
Expand All @@ -169,8 +218,11 @@ int launchSimulation()
// Attach world as a mvsim communications node:
world->connectToServer();

// Prepare selfdriving classes, now that we have the world initialized:
prepare_selfdriving(*world);

// Launch GUI thread:
TThreadParams thread_params;
GUI_ThreadParams thread_params;
thread_params.world = world;

std::thread thGUI =
Expand Down Expand Up @@ -282,9 +334,13 @@ int launchSimulation()

} // end while()

// Close GUI thread:
thread_params.closing(true);
if (thGUI.joinable()) thGUI.join();

thGUI.join(); // TODO: It could break smth
// Close selfdriving thread:
sd.sdThreadParams.closing(true);
if (sd.selfDrivingThread.joinable()) sd.selfDrivingThread.join();

return 0;
}
Expand Down Expand Up @@ -390,10 +446,7 @@ void prepare_selfdriving_window(
}

auto btn = pnNav->add<nanogui::Button>("START");

btn->setCallback([]() {
// XX
});
btn->setCallback([]() { sd.navigator.requestNavigation(sd.waypts); });
}

// -------------------------------
Expand Down Expand Up @@ -472,7 +525,7 @@ void prepare_selfdriving_window(
grid->getOccGrid().getAsPointCloud(*obsPts);
});

sd.obstacles =
auto obstacles =
selfdriving::ObstacleSource::FromStaticPointcloud(obsPts);

sd.pi.stateStart.pose.fromString(edStateStartPose->value());
Expand All @@ -481,7 +534,7 @@ void prepare_selfdriving_window(
sd.pi.stateGoal.pose.fromString(edStateGoalPose->value());
sd.pi.stateGoal.vel.fromString(edStateGoalVel->value());

sd.pi.obstacles = sd.obstacles;
sd.pi.obstacles = obstacles;

auto bbox = sd.pi.obstacles->obstacles()->boundingBox();

Expand Down Expand Up @@ -602,7 +655,7 @@ void prepare_selfdriving_window(
gui->performLayout();
}

void mvsim_server_thread_update_GUI(TThreadParams& tp)
void mvsim_server_thread_update_GUI(GUI_ThreadParams& tp)
{
while (!tp.isClosing())
{
Expand Down Expand Up @@ -634,6 +687,29 @@ void mvsim_server_thread_update_GUI(TThreadParams& tp)
}
}

void selfdriving_run_thread(SelfDrivingThreadParams& params)
{
double rateHz = 10.0;

mrpt::system::CRateTimer rate(rateHz);

while (!params.isClosing())
{
try
{
sd.navigator.navigationStep();
rate.sleep();
}
catch (const std::exception& e)
{
std::cerr << "[selfdriving_run_thread] Exception:" << e.what()
<< std::endl;
params.closing(true);
return;
}
}
}

int main(int argc, char** argv)
{
try
Expand All @@ -651,8 +727,6 @@ int main(int argc, char** argv)
}
}

prepare_selfdriving();

launchSimulation();
}
catch (const std::exception& e)
Expand Down
29 changes: 9 additions & 20 deletions libselfdriving/include/selfdriving/algos/WaypointSequencer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <mrpt/poses/CPose2DInterpolator.h>
#include <mrpt/system/COutputLogger.h>
#include <mrpt/system/CTimeLogger.h>
#include <selfdriving/data/TrajectoriesAndRobotShape.h>
#include <selfdriving/data/Waypoints.h>
#include <selfdriving/interfaces/ObstacleSource.h>
#include <selfdriving/interfaces/VehicleMotionInterface.h>
Expand Down Expand Up @@ -92,12 +93,14 @@ class WaypointSequencer : public mrpt::system::COutputLogger
{
Configuration() = default;

/** @name Interfaces (fill all these members before initialize() )
/** @name Mandatory configuration fields; must fill before initialize()
* @{ */
VehicleMotionInterface::Ptr vehicleMotionInterface;

ObstacleSource::Ptr obstacleSource;

TrajectoriesAndRobotShape ptgs;

/** @} */

/** @name Parameters
Expand Down Expand Up @@ -226,27 +229,13 @@ class WaypointSequencer : public mrpt::system::COutputLogger
/** mutex for all navigation methods */
std::recursive_mutex m_nav_cs;

struct RobotPoseVel
{
mrpt::math::TPose2D pose;
mrpt::math::TTwist2D velGlobal, velLocal;
/** raw odometry (frame does not match to "pose", but is expected to be
* smoother in the short term). */
mrpt::math::TPose2D rawOdometry;
mrpt::system::TTimeStamp timestamp;
/** map frame ID for `pose` */
std::string pose_frame_id;

RobotPoseVel() = default;
};

/** Current robot pose (updated in CAbstractNavigator::navigationStep() ) */
RobotPoseVel m_curPoseVel;
mrpt::Clock::time_point m_last_curPoseVelUpdate_robot_time;
// std::string m_last_curPoseVelUpdate_pose_frame_id;
/** Current robot pose (updated in navigationStep() ) */
VehicleLocalizationState lastVehicleLocalization_;
VehicleOdometryState lastVehicleOdometry_;
double lastVehiclePosRobotTime_ = 0;

/** Latest robot poses (updated in CAbstractNavigator::navigationStep() ) */
mrpt::poses::CPose2DInterpolator m_latestPoses, m_latestOdomPoses;
mrpt::poses::CPose2DInterpolator latestPoses_, latestOdomPoses_;

/** For sending an alarm (error event) when it seems that we are not
* approaching toward the target in a while... */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* -------------------------------------------------------------------------
* SelfDriving C++ library based on PTGs and mrpt-nav
* Copyright (C) 2019-2021 Jose Luis Blanco, University of Almeria
* See LICENSE for license information.
* ------------------------------------------------------------------------- */

#pragma once

#include <mvsim/Comms/Client.h>
#include <mvsim/mvsim-msgs/SrvGetPose.pb.h>
#include <mvsim/mvsim-msgs/SrvGetPoseAnswer.pb.h>
#include <selfdriving/interfaces/VehicleMotionInterface.h>

namespace selfdriving
{
/** Vehicle adaptor class for the MVSIM simulator.
*
*/
class MVSIM_VehicleInterface : public VehicleMotionInterface
{
public:
MVSIM_VehicleInterface() {}

/** Connect to the MVSIM server.
*/
void connect()
{
MRPT_LOG_INFO("Connecting to mvsim server...");
connection_.connect();
MRPT_LOG_INFO("Connected OK.");
}

// See base class docs
VehicleLocalizationState get_localization() override
{
mvsim_msgs::SrvGetPose req;
req.set_objectid(robotName_);

mvsim_msgs::SrvGetPoseAnswer ans;
connection_.callService("get_pose", req, ans);

VehicleLocalizationState vls;
vls.frame_id = "map";
vls.timestamp = mrpt::Clock::now();
vls.valid = true;

vls.pose.x = ans.pose().x();
vls.pose.y = ans.pose().y();
vls.pose.phi = ans.pose().yaw();

return vls;
}

// See base class docs
VehicleOdometryState get_odometry() override
{
//
return {};
}

// See base class docs
bool motion_execute(
const std::optional<CVehicleVelCmd::Ptr>& immediate,
const std::optional<EnqueuedMotionCmd>& next) override
{
return true;
}

// See base class docs
void stop(const STOP_TYPE stopType) override
{
//
}

private:
mvsim::Client connection_{"MVSIM_VehicleInterface"};
std::string robotName_ = "r1";
};

} // namespace selfdriving
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ class VehicleMotionInterface : public mrpt::system::COutputLogger
MRPT_LOG_INFO("Default start_watchdog() called.");
}

/** Returns clockwall time (UNIX timestamp as double) for real robots
* [default], simulated time in simulators. */
virtual double robot_time() const { return mrpt::Clock::nowDouble(); }

/** @name Event callbacks
* @{ */

Expand Down

0 comments on commit c30df8b

Please sign in to comment.