46 #include <unordered_map> 47 #include <unordered_set> 52 #include <tf_conversions/tf_kdl.h> 54 #include <XmlRpcException.h> 66 moveit::core::RobotModelConstPtr robot_model;
67 const moveit::core::JointModelGroup* joint_model_group;
70 std::string solver_class_name;
96 #define LOG_STREAM (std::cerr) 98 template <
class T>
inline void vprint(std::ostream& s,
const T& a) { s << a << std::endl; }
99 template <
class T,
class... AA>
inline void vprint(std::ostream& s,
const T& a,
const AA&... aa)
105 #define LOG2(...) vprint(LOG_STREAM, "ikbio ", __VA_ARGS__) 108 #define LOG(...) LOG2(__VA_ARGS__) 113 #define LOG_VAR(v) LOG2(#v, (v)); 124 LOG_STREAM.flush(); \ 125 std::stringstream ss; \ 126 vprint(ss, __VA_ARGS__); \ 127 throw std::runtime_error(ss.str()); \ 133 #ifdef ENABLE_PROFILER 140 const char*
volatile name;
141 std::atomic<int> counter;
149 template <
class force_weak_linker_symbol =
void> ProfilerBin* getProfilerBuffer()
151 static std::vector<ProfilerBin> buffer(10000);
152 return buffer.data();
156 template <
class force_weak_linker_symbol =
void> ProfilerBin* getProfilerSegment()
158 static size_t index = 0;
159 return getProfilerBuffer() + (index++) * 20;
161 static ProfilerBin* profiler_segment = getProfilerSegment();
172 template <
class force_weak_linker_symbol =
void> ProfilerInfo& getProfilerInfo()
174 static ProfilerInfo info;
177 static ProfilerInfo& profiler_info = getProfilerInfo();
180 template <
size_t ID>
struct ProfilerScope
182 __attribute__((always_inline))
inline ProfilerScope(
const char* name)
184 if(profiler_info.stack_begin == 0)
return;
185 if(this < profiler_info.stack_begin || this > profiler_info.stack_end)
return;
186 profiler_segment[ID].name = name;
188 __attribute__((always_inline))
inline ~ProfilerScope()
190 if(profiler_info.stack_begin == 0)
return;
191 if(this < profiler_info.stack_begin || this > profiler_info.stack_end)
return;
192 profiler_segment[ID].name = 0;
195 #define FNPROFILER() volatile ProfilerScope<__COUNTER__> _profilerscope(__func__); 196 #define BLOCKPROFILER(name) volatile ProfilerScope<__COUNTER__> _profilerscope(name); 202 __attribute__((always_inline))
inline ThreadScope(
const char* name,
size_t id)
205 if(profiler_info.stack_begin == 0)
return;
206 profiler_segment[id].name = name;
208 __attribute__((always_inline))
inline ~ThreadScope()
210 if(profiler_info.stack_begin == 0)
return;
211 profiler_segment[id].name = 0;
214 #define THREADPROFILER(name, id) \ 215 static const char* _threadscope_names[] = {name "0", name "1", name "2", name "3"}; \ 216 volatile ThreadScope _threadscope(_threadscope_names[id], __COUNTER__ + id); \ 217 (__COUNTER__, __COUNTER__, __COUNTER__, __COUNTER__, __COUNTER__); 223 __attribute__((always_inline))
inline CounterScope(
const char* name,
size_t id)
226 if(profiler_info.stack_begin == 0)
return;
227 if((profiler_segment[
id].counter++) == 0) profiler_segment[id].name = name;
229 __attribute__((always_inline))
inline ~CounterScope()
231 if(profiler_info.stack_begin == 0)
return;
232 if((--profiler_segment[
id].counter) == 0) profiler_segment[id].name = 0;
235 #define COUNTERPROFILER(name) volatile CounterScope _counterscope(name, __COUNTER__); 241 volatile int exit_flag;
245 pthread_getattr_np(pthread_self(), &attr);
248 pthread_attr_getstack(&attr, &stack_addr, &stack_size);
249 profiler_info.stack_begin = stack_addr;
250 profiler_info.stack_end = (
char*)stack_addr + stack_size;
251 const size_t maxbin = 1000;
252 static std::mutex mutex;
253 static std::unordered_map<const char*, size_t> samples;
255 std::thread t([
this]() {
256 auto* profiler_bins = getProfilerBuffer();
259 for(
int iter = 0; iter < 100; iter++)
261 for(
int iter = 0; iter < 100; iter++)
263 int i = rand() % maxbin;
264 const char* p = profiler_bins[i].name;
268 std::this_thread::sleep_for(std::chrono::duration<size_t, std::micro>(rand() % 1000));
271 double thistime = ros::WallTime::now().toSec();
272 static double lasttime = 0.0;
273 if(thistime < lasttime + 1)
continue;
275 static std::vector<std::pair<const char*, size_t>> data;
277 for(
auto& p : samples)
279 std::sort(data.begin(), data.end(), [](
const std::pair<const char*, size_t>& a,
const std::pair<const char*, size_t>& b) {
return a.second > b.second; });
284 double v = d.second * 100.0 / data[0].second;
286 sprintf(s,
"%6.2f%%", v);
287 LOG(
"p", s, d.first);
294 std::swap(thread, t);
301 static void start() {
static Profiler profiler; }
307 #define BLOCKPROFILER(name) 308 #define THREADPROFILER(name, id) 309 #define COUNTERPROFILER(name) 313 static void start() {}
318 __attribute__((always_inline))
inline double mix(
double a,
double b,
double f) {
return a * (1.0 - f) + b * f; }
320 __attribute__((always_inline))
inline double clamp(
double v,
double lo,
double hi)
327 __attribute__((always_inline))
inline double clamp2(
double v,
double lo,
double hi)
329 if(__builtin_expect(v < lo, 0)) v = lo;
330 if(__builtin_expect(v > hi, 0)) v = hi;
334 __attribute__((always_inline))
inline double smoothstep(
float a,
float b,
float v)
336 v = clamp((v - a) / (b - a), 0.0, 1.0);
337 return v * v * (3.0 - 2.0 * v);
340 __attribute__((always_inline))
inline double sign(
double f)
342 if(f < 0.0) f = -1.0;
343 if(f > 0.0) f = +1.0;
349 std::uniform_int_distribution<t> base;
358 template <
class generator>
inline t operator()(generator& g)
362 t v = base(g) + base(g);
363 if(v < n)
return n - v - 1;
374 : v(88172645463325252ull)
377 __attribute__((always_inline))
inline uint64_t operator()()
397 template <
class BASE,
class... ARGS>
class Factory 399 typedef BASE* (*Constructor)(ARGS...);
403 std::type_index type;
404 virtual BASE* create(ARGS... args)
const = 0;
405 virtual BASE* clone(
const BASE*)
const = 0;
411 typedef std::set<ClassBase*> MapType;
412 static MapType& classes()
419 template <
class DERIVED>
struct Class : ClassBase
421 BASE* create(ARGS... args)
const {
return new DERIVED(args...); }
422 BASE* clone(
const BASE* o)
const {
return new DERIVED(*(
const DERIVED*)o); }
423 Class(
const std::string& name)
426 this->type =
typeid(DERIVED);
427 classes().insert(
this);
429 ~
Class() { classes().erase(
this); }
431 static BASE* create(
const std::string& name, ARGS... args)
433 for(
auto* f : classes())
434 if(f->name == name)
return f->create(args...);
435 ERROR(
"class not found", name);
437 template <
class DERIVED>
static DERIVED* clone(
const DERIVED* o)
439 for(
auto* f : classes())
440 if(f->type ==
typeid(*o))
return (DERIVED*)f->clone(o);
441 ERROR(
"class not found",
typeid(*o).name());
448 typedef size_t size_type;
449 typedef ptrdiff_t difference_type;
451 typedef const T* const_pointer;
452 typedef T& reference;
453 typedef const T& const_reference;
454 typedef T value_type;
455 T* allocate(
size_t s,
const void* hint = 0)
458 if(posix_memalign(&p, A,
sizeof(T) * s + 64))
throw std::bad_alloc();
461 void deallocate(T* ptr,
size_t s) { free(ptr); }
469 template <
class T>
struct aligned_vector : std::vector<T, aligned_allocator<T, 32>>
476 typedef XmlRpc::XmlRpcValue var;
487 void conv(
bool& r) { r = (bool)v; }
488 void conv(
double& r) { r = (v.getType() == var::TypeInt) ? ((
double)(int)v) : ((double)v); }
489 void conv(tf2::Vector3& r)
495 r = tf2::Vector3(x, y, z);
497 void conv(tf2::Quaternion& r)
504 r = tf2::Quaternion(x, y, z, w).normalized();
506 void conv(std::string& r) { r = (std::string)v; }
509 template <
class T>
void param(
const char* key, T& r)
511 if(!v.hasMember(key))
return;
516 catch(
const XmlRpc::XmlRpcException& e)