diff --git a/CMakeLists.txt b/CMakeLists.txt index 952f8c4a..b887fa00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,14 @@ add_custom_target(clean_all ) +add_custom_target(lint + COMMAND ${CMAKE_COMMAND} + -DCHECK_NO_AUTO_SOURCE_DIR=${CMAKE_SOURCE_DIR} + -P ${CMAKE_SOURCE_DIR}/cmake/CheckNoAuto.cmake + COMMENT "Checking coding style" +) + + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_BINARY_DIR}/lifelong; ${CMAKE_BINARY_DIR}/build; @@ -61,6 +69,11 @@ set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES option(BUILD_TESTS "Build planner tests" ON) if(BUILD_TESTS) enable_testing() + add_test(NAME no_auto_lint + COMMAND ${CMAKE_COMMAND} + -DCHECK_NO_AUTO_SOURCE_DIR=${CMAKE_SOURCE_DIR} + -P ${CMAKE_SOURCE_DIR}/cmake/CheckNoAuto.cmake) + add_executable(multi_step_plan_test tests/multi_step_plan_test.cpp ${DEFAULT_PLANNER_SOURCES} @@ -89,4 +102,3 @@ if(BUILD_TESTS) add_test(NAME python_interface_test COMMAND python_interface_test WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) endif() - diff --git a/Coding_Style.md b/Coding_Style.md new file mode 100644 index 00000000..f436a6e0 --- /dev/null +++ b/Coding_Style.md @@ -0,0 +1,13 @@ +# Coding Style + +The start kit uses C++17. Prefer clear, explicit types in public and starter code so submissions remain easy to read and debug. + +## Linting + +Run the style check from a configured build directory: + +```shell +cmake --build build --target lint +``` + +The `lint` target rejects use of the C++ `auto` keyword in start-kit source and test files. Use explicit types instead. diff --git a/README.md b/README.md index 5b7e19d5..a7380209 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,10 @@ cmake -B build ./ -DCMAKE_BUILD_TYPE=Release make -C build -j ``` +## Coding style + +See [Coding_Style.md](./Coding_Style.md). After configuring CMake, run `cmake --build build --target lint` to check the no-`auto` style rule. + ## Run the start kit Running the start-kit using commands: diff --git a/cmake/CheckNoAuto.cmake b/cmake/CheckNoAuto.cmake new file mode 100644 index 00000000..693377ca --- /dev/null +++ b/cmake/CheckNoAuto.cmake @@ -0,0 +1,40 @@ +set(CHECK_NO_AUTO_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." CACHE PATH "Repository root to scan") + +set(CHECK_NO_AUTO_PATTERNS + "default_planner/*.cpp" + "default_planner/*.h" + "inc/*.h" + "src/*.cpp" + "src/*.h" + "tests/*.cpp" + "tests/*.h" + "python/common/*.cpp" + "python/common/*.h") + +set(files) +foreach(pattern IN LISTS CHECK_NO_AUTO_PATTERNS) + file(GLOB matched "${CHECK_NO_AUTO_SOURCE_DIR}/${pattern}") + list(APPEND files ${matched}) +endforeach() + +set(found_auto FALSE) +foreach(file IN LISTS files) + if(file MATCHES "/inc/nlohmann/") + continue() + endif() + file(STRINGS "${file}" lines) + set(line_number 0) + foreach(line IN LISTS lines) + math(EXPR line_number "${line_number} + 1") + string(REGEX REPLACE "//.*$" "" code "${line}") + if(code MATCHES "(^|[^A-Za-z0-9_])auto([ \\t\\*&]+|$)") + file(RELATIVE_PATH rel "${CHECK_NO_AUTO_SOURCE_DIR}" "${file}") + message(SEND_ERROR "${rel}:${line_number}: use explicit types instead of auto") + set(found_auto TRUE) + endif() + endforeach() +endforeach() + +if(found_auto) + message(FATAL_ERROR "Found forbidden C++ auto keyword usage") +endif() diff --git a/default_planner/default_executor.cpp b/default_planner/default_executor.cpp index 48488e68..2f268420 100644 --- a/default_planner/default_executor.cpp +++ b/default_planner/default_executor.cpp @@ -54,7 +54,7 @@ vector execute_process_new_plan(int sync_time_limit, Plan& plan_struct, v previous_locations[i] = env->system_states[i].location; //for use of keep track of tpg in move function } - auto curr_states = predicted_states; + std::vector curr_states = predicted_states; int moves[4] = {1, env->cols, -1, -env->cols}; std::vector> plan = plan_struct.actions; @@ -102,7 +102,7 @@ vector execute_process_new_plan(int sync_time_limit, Plan& plan_struct, v for (int t = 0; t < window_size; t++) { - auto pre_states = curr_states; + std::vector pre_states = curr_states; for (int i = 0; i < env->num_of_agents; i++) { diff --git a/default_planner/heuristics.cpp b/default_planner/heuristics.cpp index 803879d5..08ffea20 100644 --- a/default_planner/heuristics.cpp +++ b/default_planner/heuristics.cpp @@ -53,7 +53,7 @@ void init_heuristic(HeuristicTable& ht, SharedEnvironment* env, int goal_locatio int get_heuristic(HeuristicTable& ht, SharedEnvironment* env, int source, Neighbors* ns){ - auto it = ht.htable.find(source); + std::unordered_map::iterator it = ht.htable.find(source); if (it != ht.htable.end() && it->second < MAX_TIMESTEP) return it->second; std::vector neighbors; @@ -75,7 +75,7 @@ int get_heuristic(HeuristicTable& ht, SharedEnvironment* env, int source, Neighb assert(next >= 0 && next < env->map.size()); //set current cost for reversed direction - auto it = ht.htable.find(next); + std::unordered_map::iterator it = ht.htable.find(next); if (it != ht.htable.end() && it->second <= cost) // if 'next' is not found in htable, that means it's MAX_TIMESTEP continue; @@ -122,7 +122,7 @@ void init_dist_2_path(Dist2Path& dp, SharedEnvironment* env, Traj& path){ int loc = path[i]; // If this location has already been visited in this label, skip it - auto it = dp.dist2path.find(loc); + std::unordered_map::iterator it = dp.dist2path.find(loc); if (it != dp.dist2path.end() && it->second.label == dp.label) { assert(it->second.cost == MAX_TIMESTEP); } @@ -138,7 +138,7 @@ void init_dist_2_path(Dist2Path& dp, SharedEnvironment* env, Traj& path){ std::pair get_source_2_path(Dist2Path& dp, SharedEnvironment* env, int source, Neighbors* ns) { - auto it_source = dp.dist2path.find(source); + std::unordered_map::iterator it_source = dp.dist2path.find(source); if (it_source != dp.dist2path.end() && it_source->second.label == dp.label && it_source->second.cost < MAX_TIMESTEP) return std::make_pair(it_source->second.cost, it_source->second.togo); @@ -153,7 +153,7 @@ std::pair get_source_2_path(Dist2Path& dp, SharedEnvironment* env, int for (int next_location : neighbors) { cost = curr.cost + 1; - auto it_next = dp.dist2path.find(next_location); + std::unordered_map::iterator it_next = dp.dist2path.find(next_location); if (it_next != dp.dist2path.end() && it_next->second.label == dp.label && cost >= it_next->second.cost) continue; dp.open.emplace_back(dp.label,next_location,cost,curr.togo); diff --git a/default_planner/pibt.cpp b/default_planner/pibt.cpp index 2b9c4f99..abf6fd62 100644 --- a/default_planner/pibt.cpp +++ b/default_planner/pibt.cpp @@ -67,7 +67,7 @@ bool causalPIBT(int curr_id, int higher_id,std::vector& prev_states, std::vector neighbors; std::vector successors; getNeighborLocs(&(lns.neighbors),neighbors,prev_loc); - for (auto& neighbor: neighbors){ + for (int& neighbor: neighbors){ assert(validateMove(prev_loc, neighbor, lns.env)); @@ -98,7 +98,7 @@ bool causalPIBT(int curr_id, int higher_id,std::vector& prev_states, }); - for (auto& next: successors){ + for (PIBT_C& next: successors){ if(occupied[next.location] && !(higher_id == -1 && prev_loc == next.location)) continue; assert(validateMove(prev_loc, next.location, lns.env)); diff --git a/default_planner/planner.cpp b/default_planner/planner.cpp index 6797dc76..75ed808f 100644 --- a/default_planner/planner.cpp +++ b/default_planner/planner.cpp @@ -225,7 +225,7 @@ namespace DefaultPlanner{ static void run_multistep_pibt_once(SharedEnvironment* env, std::vector& local_priority, std::vector& one_step_actions) { - const auto start_time = std::chrono::steady_clock::now(); + const TimePoint start_time = std::chrono::steady_clock::now(); std::sort(ids.begin(), ids.end(), [&](int a, int b) { return local_priority.at(a) > local_priority.at(b); } @@ -264,7 +264,7 @@ namespace DefaultPlanner{ prev_states = next_states; - const auto elapsed_us = std::chrono::duration_cast( + const long elapsed_us = std::chrono::duration_cast( std::chrono::steady_clock::now() - start_time).count(); } @@ -353,7 +353,7 @@ namespace DefaultPlanner{ return; } - const auto episode_start = std::chrono::steady_clock::now(); + const TimePoint episode_start = std::chrono::steady_clock::now(); const TimePoint episode_deadline = episode_start + std::chrono::milliseconds(std::max(0, time_limit)); int pibt_time = PIBT_RUNTIME_PER_100_AGENTS * env->num_of_agents/100; if (pibt_time <= 0){ @@ -377,8 +377,8 @@ namespace DefaultPlanner{ setup_multistep_episode_state(env, flow_end_time, local_priority); update_guide_paths_once_for_multistep(env, flow_end_time); - const auto after_setup = std::chrono::steady_clock::now(); - const auto setup_elapsed_ms = std::chrono::duration_cast(after_setup - episode_start).count(); + const TimePoint after_setup = std::chrono::steady_clock::now(); + const long setup_elapsed_ms = std::chrono::duration_cast(after_setup - episode_start).count(); // commit only cross-episode priority update (internal rollout keeps using local_priority only) p = local_priority; diff --git a/inc/CompetitionSystem.h b/inc/CompetitionSystem.h index f9eabad4..601f60f0 100644 --- a/inc/CompetitionSystem.h +++ b/inc/CompetitionSystem.h @@ -161,7 +161,7 @@ class BaseSystem // BaseSystem(grid, planner, model) // { // int task_id = 0; -// for (auto& task_location: tasks) +// for (int& task_location: tasks) // { // all_tasks.emplace_back(task_id++, task_location); // task_queue.emplace_back(all_tasks.back().task_id, all_tasks.back().locations.front()); diff --git a/inc/States.h b/inc/States.h index 5e94ad2d..095f27c1 100644 --- a/inc/States.h +++ b/inc/States.h @@ -71,7 +71,7 @@ typedef std::vector Path; inline std::ostream & operator << (std::ostream &out, const Path &path) { - for (auto state : path) + for (State state : path) { if (state.location < 0) continue; diff --git a/inc/TaskManager.h b/inc/TaskManager.h index 9b866559..af59a034 100644 --- a/inc/TaskManager.h +++ b/inc/TaskManager.h @@ -45,7 +45,7 @@ class TaskManager{ { finished_tasks.resize(num_of_agents); current_assignment.resize(num_of_agents); - for (auto & t: current_assignment) + for (int & t: current_assignment) t = -1; // events.resize(num_of_agents); actual_schedule.resize(num_of_agents); diff --git a/inc/Tasks.h b/inc/Tasks.h index b51fd7b7..f183fc91 100644 --- a/inc/Tasks.h +++ b/inc/Tasks.h @@ -35,7 +35,7 @@ struct Task //Task(int task_id, int location): task_id(task_id), locations({location}) {}; Task(int task_id, list location, int t_revealed): task_id(task_id), t_revealed(t_revealed) { - for (auto loc: location) + for (int loc: location) locations.push_back(loc); }; diff --git a/inc/common.h b/inc/common.h index 79449f56..96f67377 100644 --- a/inc/common.h +++ b/inc/common.h @@ -213,7 +213,7 @@ inline DelayConfig parse_delay_config(const nlohmann::json& data) throw std::invalid_argument("Missing required object delayConfig in the input JSON"); } - const auto& delay_json = data.at("delayConfig"); + const nlohmann::json& delay_json = data.at("delayConfig"); DelayConfig config; config.seed = read_required_json_param(delay_json, "seed", "delayConfig"); config.minDelay = read_required_json_param(delay_json, "minDelay", "delayConfig"); diff --git a/python/common/opaque_types.h b/python/common/opaque_types.h index 7e8d1262..da3f5954 100644 --- a/python/common/opaque_types.h +++ b/python/common/opaque_types.h @@ -2,7 +2,7 @@ * opaque_types.h — Shared PYBIND11_MAKE_OPAQUE declarations. * * MUST be included in every translation unit that touches these types via pybind11. - * This prevents pybind11 from auto-converting containers to Python lists (which copies data). + * This prevents pybind11 from implicitly converting containers to Python lists (which copies data). * Instead, Python gets a thin wrapper referencing C++ memory directly (zero-copy). * * Include this INSTEAD of in bridge files. diff --git a/python/common/pyExecutor.cpp b/python/common/pyExecutor.cpp index ce8cff0d..3e7f24a7 100644 --- a/python/common/pyExecutor.cpp +++ b/python/common/pyExecutor.cpp @@ -46,7 +46,7 @@ vector pyExecutor::process_new_plan(int sync_time_limit, Plan & plan, vec // Python returns predicted_states (list of State). // Since State is a registered type, we can iterate and cast. std::vector predicted; - for (auto s : result) { + for (const py::handle& s : result) { predicted.push_back(s.cast()); } return predicted; @@ -57,7 +57,7 @@ void pyExecutor::next_command(int exec_time_limit, std::vector py::gil_scoped_acquire acquire; py::object result = py_executor.attr("next_command")(exec_time_limit); agent_command.clear(); - for (auto cmd : result) { + for (const py::handle& cmd : result) { agent_command.push_back(static_cast(cmd.cast())); } } diff --git a/python/common/pyMAPFPlanner.cpp b/python/common/pyMAPFPlanner.cpp index 05ba0199..734be558 100644 --- a/python/common/pyMAPFPlanner.cpp +++ b/python/common/pyMAPFPlanner.cpp @@ -41,9 +41,9 @@ void pyMAPFPlanner::plan(int time_limit, Plan & plan) // Convert Python list of lists of Action (int) to C++ vector> plan.actions.clear(); - for (auto agent_actions : py_actions) { + for (const py::handle& agent_actions : py_actions) { std::vector actions_vec; - for (auto act : agent_actions) { + for (const py::handle& act : agent_actions) { actions_vec.push_back(static_cast(act.cast())); } plan.actions.push_back(std::move(actions_vec)); diff --git a/python/common/pyTaskScheduler.cpp b/python/common/pyTaskScheduler.cpp index 372f8f01..d235a3a8 100644 --- a/python/common/pyTaskScheduler.cpp +++ b/python/common/pyTaskScheduler.cpp @@ -37,7 +37,7 @@ void pyTaskScheduler::plan(int time_limit, std::vector & proposed_schedule) py::gil_scoped_acquire acquire; py::list result = py_scheduler.attr("plan")(time_limit); proposed_schedule.clear(); - for (auto item : result) { + for (const py::handle& item : result) { proposed_schedule.push_back(item.cast()); } } diff --git a/src/ActionModel.cpp b/src/ActionModel.cpp index 75a58541..34896a75 100644 --- a/src/ActionModel.cpp +++ b/src/ActionModel.cpp @@ -288,7 +288,7 @@ void collect_neighbor_agents(int agent_id, const BoxMotion& motion, StepResolveC for (int c = c0; c <= c1; c++) { const int key = r * ctx.cols + c; - auto it = ctx.current_bins.find(key); + unordered_map>::const_iterator it = ctx.current_bins.find(key); if (it == ctx.current_bins.end()) continue; for (int j : it->second) @@ -524,7 +524,7 @@ vector ActionModelWithRotate::get_real_loca for (size_t i = 0; i < state.size(); i++) { - const auto& s = state[i]; + const State& s = state[i]; RealLocation loc; const int row = s.location / cols; const int col = s.location % cols; @@ -632,7 +632,7 @@ void ActionModelWithRotate::sanity_check_states(const vector& states) const int nc = col + kDc[k]; if (nr < 0 || nr >= rows || nc < 0 || nc >= cols) continue; - auto it = grid_agents.find(nr * cols + nc); + unordered_map>::iterator it = grid_agents.find(nr * cols + nc); if (it == grid_agents.end()) continue; for (int j : it->second) diff --git a/src/CompetitionSystem.cpp b/src/CompetitionSystem.cpp index 165d22e7..2a9ad4ca 100644 --- a/src/CompetitionSystem.cpp +++ b/src/CompetitionSystem.cpp @@ -83,10 +83,10 @@ bool BaseSystem::planner_initialize() { using namespace std::placeholders; std::packaged_task init_task(std::bind(&Entry::initialize, planner, _1)); - auto init_future = init_task.get_future(); + std::future init_future = init_task.get_future(); env->plan_start_time = std::chrono::steady_clock::now(); - auto init_td = std::thread(std::move(init_task), preprocess_time_limit); + std::thread init_td = std::thread(std::move(init_task), preprocess_time_limit); if (init_future.wait_for(std::chrono::milliseconds(preprocess_time_limit)) == std::future_status::ready) { init_td.join(); @@ -136,7 +136,7 @@ void BaseSystem::simulate(int simulation_time, int chunk_size) { task_td.join(); started = false; - auto res = future.get(); + bool res = future.get(); logger->log_info("planner returns", simulator.get_curr_timestep()); } else @@ -149,23 +149,23 @@ void BaseSystem::simulate(int simulation_time, int chunk_size) { //wait for initial planning to finish and at the same time move all wait logger->log_info("planner (initilal planning) cannot run because the previous run is still running", simulator.get_curr_timestep()); - auto deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(simulator_time_limit); + std::chrono::steady_clock::time_point deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(simulator_time_limit); //main thread move drives by calling simulator.move simulator.move_all_wait(1); - auto move_end = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point move_end = std::chrono::steady_clock::now(); while(deadline < move_end) { //move takes more time than simulator_time_limit, extend deadline deadline += std::chrono::milliseconds(simulator_time_limit); } // wait until deadline OR planner finishes early - const auto st = future.wait_until(deadline); + const std::future_status st = future.wait_until(deadline); if (st == std::future_status::ready) { task_td.join(); started = false; - auto res = future.get(); + bool res = future.get(); logger->log_info("planner (initilal planning) returns", simulator.get_curr_timestep()); } else @@ -183,13 +183,13 @@ void BaseSystem::simulate(int simulation_time, int chunk_size) //check if planenr finished if (remain_communication_time <= 0 && started) { - auto deadline = plan_start + std::chrono::milliseconds(min_comm_time - remain_communication_time); - const auto st = future.wait_until(deadline); + std::chrono::steady_clock::time_point deadline = plan_start + std::chrono::milliseconds(min_comm_time - remain_communication_time); + const std::future_status st = future.wait_until(deadline); if (st == std::future_status::ready) { task_td.join(); started = false; - auto res = future.get(); + bool res = future.get(); logger->log_info("planner returns", simulator.get_curr_timestep()); } else @@ -224,9 +224,9 @@ void BaseSystem::simulate(int simulation_time, int chunk_size) //while the planner is running, move from previous plans sync_shared_env_executor(); - auto move_start = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point move_start = std::chrono::steady_clock::now(); curr_states = simulator.move(simulator_time_limit); - auto move_end = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point move_end = std::chrono::steady_clock::now(); int elapsed_tick =std::max(1, ((int)std::chrono::duration_cast(move_end - move_start).count() + simulator_time_limit - 1) / simulator_time_limit); remain_communication_time -= elapsed_tick*simulator_time_limit; @@ -282,17 +282,17 @@ void BaseSystem::initialize() int timestep = simulator.get_curr_timestep(); std::packaged_task init_task(std::bind(&Entry::initialize, planner, std::placeholders::_1)); - auto init_future = init_task.get_future(); + std::future init_future = init_task.get_future(); - auto init_start_time = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point init_start_time = std::chrono::steady_clock::now(); env->plan_start_time = init_start_time; exec_env->plan_start_time = init_start_time; - auto init_deadline = init_start_time + std::chrono::milliseconds(preprocess_time_limit); + std::chrono::steady_clock::time_point init_deadline = init_start_time + std::chrono::milliseconds(preprocess_time_limit); std::thread init_td(std::move(init_task), preprocess_time_limit); simulator.initialise_executor(preprocess_time_limit); - auto init_end_time = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point init_end_time = std::chrono::steady_clock::now(); int diff = (int)std::chrono::duration_cast(init_end_time - init_start_time).count(); @@ -370,7 +370,7 @@ void BaseSystem::saveResults(const string &fileName, int screen, bool pretty_pri { // Save events json event = json::array(); - for(auto e: task_manager.events) + for(std::tuple e: task_manager.events) { json ev = json::array(); int timestep; @@ -409,7 +409,7 @@ void BaseSystem::saveResults(const string &fileName, int screen, bool pretty_pri { std::string schedules; bool first = true; - for (const auto schedule : task_manager.actual_schedule[i]) + for (const std::pair schedule : task_manager.actual_schedule[i]) { if (!first) { @@ -436,7 +436,7 @@ void BaseSystem::saveResults(const string &fileName, int screen, bool pretty_pri { std::string schedules; bool first = true; - for (const auto schedule : task_manager.planner_schedule[i]) + for (const std::pair schedule : task_manager.planner_schedule[i]) { if (!first) { @@ -460,7 +460,7 @@ void BaseSystem::saveResults(const string &fileName, int screen, bool pretty_pri // Save errors json schedule_errors = json::array(); - for (auto error: task_manager.schedule_errors) + for (std::tuple error: task_manager.schedule_errors) { std::string error_msg; int t_id; diff --git a/src/DelayGenerator.cpp b/src/DelayGenerator.cpp index 7e5a1dfa..0ad71669 100644 --- a/src/DelayGenerator.cpp +++ b/src/DelayGenerator.cpp @@ -155,10 +155,10 @@ void DelayGenerator::clear_active_delays() nlohmann::ordered_json DelayGenerator::delay_intervals_to_json() const { nlohmann::ordered_json result = nlohmann::ordered_json::array(); - for (const auto& agent_intervals : delay_intervals) + for (const std::vector>& agent_intervals : delay_intervals) { nlohmann::ordered_json agent_json = nlohmann::ordered_json::array(); - for (const auto& interval : agent_intervals) + for (const std::pair& interval : agent_intervals) { agent_json.push_back({interval.first, interval.second}); } diff --git a/src/Evaluation.cpp b/src/Evaluation.cpp index c23dc6a7..e66a1113 100644 --- a/src/Evaluation.cpp +++ b/src/Evaluation.cpp @@ -3,12 +3,12 @@ void DummyPlanner::load_plans(std::string fname){ std::ifstream ifs(fname); - auto jf = nlohmann::json::parse(ifs); + nlohmann::json jf = nlohmann::json::parse(ifs); if (!jf.contains("Planner Paths") || !jf["Planner Paths"].is_array()){ return; } - for (auto it = jf["Planner Paths"].begin(); it != jf["Planner Paths"].end(); ++it) + for (nlohmann::json::iterator it = jf["Planner Paths"].begin(); it != jf["Planner Paths"].end(); ++it) { if (!it->is_string()) { @@ -16,7 +16,7 @@ void DummyPlanner::load_plans(std::string fname){ return; } agent_plans.emplace_back(); - for (auto& ch: it->get()) + for (char ch: it->get_ref()) { if (ch=='W') { @@ -42,7 +42,7 @@ void DummyPlanner::load_plans(std::string fname){ std::vector DummyPlanner::plan(int time_limit) { std::vector result; - for (auto & dq: agent_plans) + for (std::deque & dq: agent_plans) { if (!dq.empty()) { diff --git a/src/Simulator.cpp b/src/Simulator.cpp index 6160cd7c..59c5ea8a 100644 --- a/src/Simulator.cpp +++ b/src/Simulator.cpp @@ -103,9 +103,9 @@ void Simulator::process_new_plan(int sync_time_limit, int overtime_runtime, Plan const std::vector> planned_actions = plan.convert_to_actions(); //call executor to process the new plan and get staged actions - auto process_start = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point process_start = std::chrono::steady_clock::now(); predict_states = executor->process_new_plan(sync_time_limit, plan, staged_actions); - auto process_end = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point process_end = std::chrono::steady_clock::now(); if (executor_validation) validate_staged_actions_prefix(previous_staged_actions, planned_actions, staged_actions); @@ -132,9 +132,9 @@ vector Simulator::move(int move_time_limit) //move one single 100ms step // reserve space for the executor to write commands agent_command.resize(num_of_agents); - auto process_start = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point process_start = std::chrono::steady_clock::now(); executor->next_command(move_time_limit, agent_command); - auto process_end = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point process_end = std::chrono::steady_clock::now(); int diff = (int)std::chrono::duration_cast(process_end - process_start).count() - move_time_limit; std::vector actions(num_of_agents, Action::W); //default action is wait @@ -182,7 +182,7 @@ vector Simulator::move(int move_time_limit) //move one single 100ms step // cout<<"planned movement for agent "< pre_states = curr_states; curr_states = model->step(curr_states, actions,timestep); timestep++; @@ -229,7 +229,7 @@ void Simulator::record_planned_movements(Action action, int agent_id) if (current_planner_chunk_count[agent_id] > 0) { assert(!chunked_planner_movements[agent_id][current_planner_chunk_index[agent_id]].empty()); - auto last_movement = chunked_planner_movements[agent_id][current_planner_chunk_index[agent_id]].back().first; + Action last_movement = chunked_planner_movements[agent_id][current_planner_chunk_index[agent_id]].back().first; if (last_movement == action) { is_different_action = false; @@ -263,7 +263,7 @@ void Simulator::record_actual_movements(State state, Action action, int agent_id if (current_actual_chunk_count[agent_id] > 0) { assert(!chunked_actual_movements[agent_id][current_actual_chunk_index[agent_id]].empty()); - auto last_movement = chunked_actual_movements[agent_id][current_actual_chunk_index[agent_id]].back().first; + Action last_movement = chunked_actual_movements[agent_id][current_actual_chunk_index[agent_id]].back().first; if (last_movement == action) { is_different_action = false; @@ -299,7 +299,7 @@ void Simulator::simulate_delay() } delay_generator->nextTick(); - const auto& remaining_delays = delay_generator->get_remaining_delays(); + const std::vector& remaining_delays = delay_generator->get_remaining_delays(); for (int agent = 0; agent < num_of_agents; agent++) { curr_states[agent].delay.inDelay = remaining_delays[agent] > 0; @@ -357,7 +357,7 @@ json Simulator::actual_path_to_json() const { std::string path; int curr_steps = 0; - for (const auto& chunk : chunked_actual_movements[i]) + for (const std::list>& chunk : chunked_actual_movements[i]) { path+="[("; path+=std::to_string(curr_steps); @@ -372,7 +372,7 @@ json Simulator::actual_path_to_json() const path+="):("; bool first = true; - for (const auto& action_pair : chunk) + for (const std::pair& action_pair : chunk) { Action action = action_pair.first; int duration = action_pair.second; @@ -425,7 +425,7 @@ json Simulator::planned_path_to_json() const { std::string path; int curr_steps = 0; - for (const auto& chunk : chunked_planner_movements[i]) + for (const std::list>& chunk : chunked_planner_movements[i]) { path+="[("; path+=std::to_string(curr_steps); @@ -439,7 +439,7 @@ json Simulator::planned_path_to_json() const path+=std::to_string(chunked_planner_snapshot_states[i][0].counter.count); path+="):("; bool first = true; - for (const auto& action_pair : chunk) + for (const std::pair& action_pair : chunk) { Action action = action_pair.first; int duration = action_pair.second; @@ -516,7 +516,7 @@ json Simulator::action_errors_to_json() const { // Save errors json errors = json::array(); - for (auto error: model->errors) + for (std::tuple error: model->errors) { std::string error_msg; int agent1; diff --git a/src/TaskManager.cpp b/src/TaskManager.cpp index a8f09a8f..03590353 100644 --- a/src/TaskManager.cpp +++ b/src/TaskManager.cpp @@ -168,7 +168,7 @@ list TaskManager::check_finished_tasks(vector& states, int timestep) void TaskManager::sync_shared_env(SharedEnvironment* env) { env->task_pool.clear(); - for (auto& task: ongoing_tasks) + for (std::pair& task: ongoing_tasks) { env->task_pool[task.first] = *task.second; } @@ -230,7 +230,7 @@ json TaskManager::to_json(int map_cols) const { json tasks = json::array(); - for (auto t: all_tasks) + for (Task* t: all_tasks) { json task = json::array(); task.push_back(t->task_id); @@ -239,7 +239,7 @@ json TaskManager::to_json(int map_cols) const // task.push_back(t->locations.front()%map_cols); task.push_back(t->t_revealed); json locs = json::array(); - for (auto loc: t->locations) + for (int loc: t->locations) { locs.push_back(loc/map_cols); locs.push_back(loc%map_cols); diff --git a/src/driver.cpp b/src/driver.cpp index c8f317e2..aefc13c8 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -102,7 +102,7 @@ int main(int argc, char **argv) bool use_py_executor = vm["executorPython"].as(); if (use_py_planner || use_py_scheduler || use_py_executor) { - auto *pe = new pyEntry(use_py_planner, use_py_scheduler, use_py_executor); + pyEntry *pe = new pyEntry(use_py_planner, use_py_scheduler, use_py_executor); executor = pe->get_executor(); planner = pe; } else { @@ -110,7 +110,7 @@ int main(int argc, char **argv) executor = new Executor(); } - auto input_json_file = vm["inputFile"].as(); + std::string input_json_file = vm["inputFile"].as(); json data; std::ifstream f(input_json_file); try @@ -124,7 +124,7 @@ int main(int argc, char **argv) exit(1); } - auto map_path = read_param_json(data, "mapFile"); + std::string map_path = read_param_json(data, "mapFile"); Grid grid(base_folder + map_path); planner->env->map_name = map_path.substr(map_path.find_last_of("/") + 1); diff --git a/tests/delay_generator_test.cpp b/tests/delay_generator_test.cpp index f6c0cbba..2e49792f 100644 --- a/tests/delay_generator_test.cpp +++ b/tests/delay_generator_test.cpp @@ -22,8 +22,8 @@ int main() for (int tick = 0; tick < 100; tick++) { - const auto lhs_events = lhs.nextTick(); - const auto rhs_events = rhs.nextTick(); + const std::vector> lhs_events = lhs.nextTick(); + const std::vector> rhs_events = rhs.nextTick(); assert(lhs_events == rhs_events); } } @@ -40,9 +40,9 @@ int main() config.gaussStdRatio = 0.0; DelayGenerator generator(config, 1); - const auto tick0 = generator.nextTick(); - const auto tick1 = generator.nextTick(); - const auto tick2 = generator.nextTick(); + const std::vector> tick0 = generator.nextTick(); + const std::vector> tick1 = generator.nextTick(); + const std::vector> tick2 = generator.nextTick(); assert(tick0.size() == 1); assert(tick0[0] == std::make_pair(0, 2)); diff --git a/tests/python_interface_test.cpp b/tests/python_interface_test.cpp index 08cb5dc4..be5fb510 100644 --- a/tests/python_interface_test.cpp +++ b/tests/python_interface_test.cpp @@ -137,7 +137,7 @@ struct TestEnv { Task t; t.task_id = i; t.t_revealed = 0; - for (auto loc : tasks[i]) { + for (int loc : tasks[i]) { t.locations.push_back(loc); } env->task_pool[i] = t; @@ -421,7 +421,7 @@ sys.modules['pyExecutor'] = dummy_executor } std::vector> staged_actions(tenv.team_size); - auto predicted = executor.process_new_plan(100, plan, staged_actions); + std::vector predicted = executor.process_new_plan(100, plan, staged_actions); ASSERT_EQ((int)predicted.size(), tenv.team_size); // staged_actions should have FW and CR appended (non-wait actions) @@ -436,7 +436,7 @@ sys.modules['pyExecutor'] = dummy_executor std::vector commands(tenv.team_size); executor.next_command(100, commands); ASSERT_EQ((int)commands.size(), tenv.team_size); - for (auto cmd : commands) { + for (ExecutionCommand cmd : commands) { ASSERT_EQ(cmd, ExecutionCommand::GO); } @@ -568,8 +568,8 @@ void run_e2e_tests() { Grid grid(base_folder + data["mapFile"].get()); int team_size = data["teamSize"].get(); - auto agents = read_int_vec(base_folder + data["agentFile"].get(), team_size); - auto tasks = read_int_vec(base_folder + data["taskFile"].get()); + std::vector agents = read_int_vec(base_folder + data["agentFile"].get(), team_size); + std::vector> tasks = read_int_vec(base_folder + data["taskFile"].get()); Entry* entry = new Entry(); Executor* executor = new Executor(entry->env); @@ -578,7 +578,7 @@ void run_e2e_tests() { Logger* logger = new Logger("", 5); // fatal only model->set_logger(logger); - auto system_ptr = std::make_unique( + std::unique_ptr system_ptr = std::make_unique( grid, entry, executor, agents, tasks, model, data.value("agentCounter", 10)); system_ptr->set_logger(logger); @@ -586,7 +586,7 @@ void run_e2e_tests() { system_ptr->set_preprocess_time_limit(5000); system_ptr->set_num_tasks_reveal(data.value("numTasksReveal", 1.0f)); - auto delay_config = parse_delay_config(data); + DelayConfig delay_config = parse_delay_config(data); system_ptr->set_delay_generator(std::make_unique(delay_config, team_size)); // Short simulation: 50 timesteps @@ -623,8 +623,8 @@ sys.modules['pyMAPFPlanner'] = dummy_planner Grid grid(base_folder + data["mapFile"].get()); int team_size = data["teamSize"].get(); - auto agents = read_int_vec(base_folder + data["agentFile"].get(), team_size); - auto tasks = read_int_vec(base_folder + data["taskFile"].get()); + std::vector agents = read_int_vec(base_folder + data["agentFile"].get(), team_size); + std::vector> tasks = read_int_vec(base_folder + data["taskFile"].get()); // Python planner + C++ scheduler + C++ executor pyEntry* entry = new pyEntry(true, false, false); @@ -635,7 +635,7 @@ sys.modules['pyMAPFPlanner'] = dummy_planner Logger* logger = new Logger("", 5); model->set_logger(logger); - auto system_ptr = std::make_unique( + std::unique_ptr system_ptr = std::make_unique( grid, entry, executor, agents, tasks, model, data.value("agentCounter", 10)); system_ptr->set_logger(logger); @@ -643,7 +643,7 @@ sys.modules['pyMAPFPlanner'] = dummy_planner system_ptr->set_preprocess_time_limit(5000); system_ptr->set_num_tasks_reveal(data.value("numTasksReveal", 1.0f)); - auto delay_config = parse_delay_config(data); + DelayConfig delay_config = parse_delay_config(data); system_ptr->set_delay_generator(std::make_unique(delay_config, team_size)); // Short simulation with Python planner (returns all-wait) @@ -680,8 +680,8 @@ void run_performance_tests() { Grid grid(base_folder + data["mapFile"].get()); int team_size = data["teamSize"].get(); - auto agents = read_int_vec(base_folder + data["agentFile"].get(), team_size); - auto tasks = read_int_vec(base_folder + data["taskFile"].get()); + std::vector agents = read_int_vec(base_folder + data["agentFile"].get(), team_size); + std::vector> tasks = read_int_vec(base_folder + data["taskFile"].get()); SharedEnvironment env; env.num_of_agents = team_size; @@ -713,7 +713,7 @@ void run_performance_tests() { Task t; t.task_id = i; t.t_revealed = 0; - for (auto loc : tasks[i]) t.locations.push_back(loc); + for (int loc : tasks[i]) t.locations.push_back(loc); env.task_pool[i] = t; } @@ -726,7 +726,7 @@ void run_performance_tests() { ASSERT_EQ(map_size, 140 * 500); ASSERT_EQ((int)env.map.size(), map_size); - auto start = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); // Iterate all cells from Python to measure access speed py::exec(R"( total = 0 @@ -734,7 +734,7 @@ m = env.map for i in range(len(m)): total += m[i] )", py::globals(), py::dict(py::arg("env") = py_env)); - auto end = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); double ms = std::chrono::duration(end - start).count(); std::cout << " Map iteration (70k cells): " << ms << " ms" << std::endl; ASSERT_LE(ms, 500.0); // Should be well under 500ms for 70k ints @@ -745,14 +745,14 @@ for i in range(len(m)): // Test: iterate 5000 agent states from Python { std::cout << " [RUN ] perf_states_iterate_5000" << std::endl; - auto start = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); py::exec(R"( states = env.curr_states locs = [] for i in range(len(states)): locs.append(states[i].location) )", py::globals(), py::dict(py::arg("env") = py_env)); - auto end = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); double ms = std::chrono::duration(end - start).count(); std::cout << " States iteration (5000 agents): " << ms << " ms" << std::endl; ASSERT_LE(ms, 200.0); // Should be fast — no copy @@ -766,7 +766,7 @@ for i in range(len(states)): int pool_size = (int)env.task_pool.size(); std::cout << " Task pool size: " << pool_size << std::endl; - auto start = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); py::exec(R"( pool = env.task_pool count = 0 @@ -774,7 +774,7 @@ for k in pool: t = pool[k] count += len(t.locations) )", py::globals(), py::dict(py::arg("env") = py_env)); - auto end = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); double ms = std::chrono::duration(end - start).count(); std::cout << " Task pool iteration (" << pool_size << " tasks): " << ms << " ms" << std::endl; ASSERT_LE(ms, 1000.0); @@ -785,14 +785,14 @@ for k in pool: // Test: iterate curr_task_schedule (5000 ints) { std::cout << " [RUN ] perf_schedule_iterate_5000" << std::endl; - auto start = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); py::exec(R"( sched = env.curr_task_schedule total = 0 for i in range(len(sched)): total += sched[i] )", py::globals(), py::dict(py::arg("env") = py_env)); - auto end = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); double ms = std::chrono::duration(end - start).count(); std::cout << " Schedule iteration (5000 agents): " << ms << " ms" << std::endl; ASSERT_LE(ms, 100.0); @@ -803,14 +803,14 @@ for i in range(len(sched)): // Test: iterate staged_actions (5000 empty vectors — check overhead of nested access) { std::cout << " [RUN ] perf_staged_actions_iterate_5000" << std::endl; - auto start = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); py::exec(R"( sa = env.staged_actions total = 0 for i in range(len(sa)): total += len(sa[i]) )", py::globals(), py::dict(py::arg("env") = py_env)); - auto end = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); double ms = std::chrono::duration(end - start).count(); std::cout << " Staged actions iteration (5000 agents): " << ms << " ms" << std::endl; ASSERT_LE(ms, 200.0); @@ -822,7 +822,7 @@ for i in range(len(sa)): { std::cout << " [RUN ] perf_planner_access_pattern" << std::endl; // Typical planner: read all states, read map cells around each agent, read schedule - auto start = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); py::exec(R"( states = env.curr_states m = env.map @@ -848,7 +848,7 @@ for iteration in range(10): # simulate 10 plan calls if c < cols - 1 and m[loc + 1] == 0: pass )", py::globals(), py::dict(py::arg("env") = py_env)); - auto end = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); double ms = std::chrono::duration(end - start).count(); std::cout << " Planner access pattern (10 iterations × 5000 agents): " << ms << " ms" << std::endl; ASSERT_LE(ms, 5000.0); // 10 full scans at 5000 agents