11#include <iCub/CamCalibModule.h> 
   12#include <yarp/math/Math.h> 
   13#include <yarp/os/Stamp.h> 
   15#define AERONAUTIC_CONVENTION 0 
   19using namespace yarp::os;
 
   20using namespace yarp::math;
 
   21using namespace yarp::sig;
 
   47    portImgOut=_portImgOut;
 
   56void CamCalibPort::onRead(ImageOf<PixelRgb> &yrpImgIn)
 
   62    double time = s.getTime();
 
   64    if (!updatePose(
time)) {
 
   68    unsigned char *pixel = yrpImgIn.getPixelAddress(0, 0);
 
   69    double *stamp = 
reinterpret_cast<double*
>(pixel);
 
   70    double backdoorTime = stamp[0];
 
   71    double backdoorRoll = stamp[1];
 
   72    double backdoorPitch = stamp[2];
 
   73    double backdoorYaw = stamp[3];
 
   75    if (
time != backdoorTime) {
 
   76        yWarning() << 
"Backdoor time:" << backdoorTime << 
"Imu time:" << 
time << 
"diff:" << (backdoorTime - 
time);
 
   84    b.addFloat64(backdoorRoll);
 
   85    b.addFloat64(backdoorPitch);
 
   86    b.addFloat64(backdoorYaw);
 
   87    b.addFloat64(backdoorRoll - roll);
 
   88    b.addFloat64(backdoorPitch - pitch);
 
   89    b.addFloat64(backdoorYaw - yaw);
 
   95    if (portImgOut!=NULL) {
 
   96        yarp::sig::ImageOf<PixelRgb> &yrpImgOut=portImgOut->prepare();
 
   99            yDebug(
"received input image after %g [s] ... ",t-t0);
 
  102        double t1=Time::now();
 
  104        if (calibTool!=NULL) {
 
  105            calibTool->
apply(yrpImgIn,yrpImgOut);
 
  107            for (
int r =0; r <yrpImgOut.height(); r++) {
 
  108                for (
int c=0; c<yrpImgOut.width(); c++) {
 
  109                    unsigned char *pixel = yrpImgOut.getPixelAddress(c,r);
 
  110                    double mean = (1.0/3.0)*(pixel[0]+pixel[1]+pixel[2]);
 
  112                    for(
int i=0; i<3; i++) {
 
  113                        double s=pixel[i]-mean;
 
  122                        pixel[i]=(
unsigned char)sn;
 
  128                yDebug(
"calibrated in %g [s]\n",Time::now()-t1);
 
  133                yDebug(
"just copied in %g [s]\n",Time::now()-t1);
 
  136        lock_guard<mutex> lck(m);
 
  145        std::snprintf(buf, 512, 
"%d %.*g %.*g %.*g %.*g", s.getCount(), DBL_DIG, s.getTime(), DBL_DIG, roll, DBL_DIG, pitch, DBL_DIG, yaw);
 
  146        pose.fromString(buf);
 
  147        portImgOut->setEnvelope(pose);
 
  149        portImgOut->writeStrict();
 
  157bool CamCalibPort::selectBottleFromMap(
double time,
 
  158                                       std::map<double, yarp::os::Bottle> *datamap,
 
  159                                       yarp::os::Bottle *bottle,
 
  162    if (datamap->size() == 0) {
 
  168        lock_guard<mutex> lck(m);
 
  172            bottle->addFloat64(m_last_imu.get(6).asFloat64());
 
  173            bottle->addFloat64(m_last_imu.get(7).asFloat64());
 
  174            bottle->addFloat64(m_last_imu.get(8).asFloat64());
 
  178            bottle->addFloat64(m_last_h_encs.get(0).asFloat64());
 
  179            bottle->addFloat64(m_last_h_encs.get(1).asFloat64());
 
  180            bottle->addFloat64(m_last_h_encs.get(2).asFloat64());
 
  187    std::map<double, yarp::os::Bottle>::iterator it_prev, it_next;
 
  190    it_next = datamap->lower_bound(
time);
 
  194    while (it_next == datamap->end() || it_next->first < 
time)
 
  198        yarp::os::Time::delay(0.001);
 
  201            yWarning() << 
"Clock out of sync, check your NTPD settings";
 
  205        it_next = datamap->lower_bound(
time);
 
  209    if(it_prev != datamap->begin()) {
 
  212    if(it_next == datamap->end() && it_next != datamap->begin()) {
 
  216    double diff_prev = 
time - it_prev->first;
 
  217    double diff_next = it_next->first - 
time;
 
  218    double diff = (diff_prev >= diff_next) ? diff_next : diff_prev;
 
  221        std::map<double, yarp::os::Bottle>::iterator it_begin, it_end;
 
  223        it_end = datamap->end();
 
  224        if(it_end != datamap->begin()) {
 
  227        it_begin = datamap->begin();
 
  231        for(std::map<double, yarp::os::Bottle>::iterator it = datamap->begin(); it != datamap->end(); ++it) {
 
  232            if (it->first > 
time) {
 
  239        double diff_end = it_end->first - 
time;
 
  240        double diff_begin = 
time - it_begin->first;
 
  241        bool err_prev = ((diff_prev >= 0.0025) || (diff_prev <= -0.0025));
 
  242        bool warn_prev = ((diff_prev >= 0.0015) || (diff_prev <= -0.0015));
 
  243        bool err_next = ((diff_next >= 0.0025) || (diff_next <= -0.0025));
 
  244        bool warn_next = ((diff_next >= 0.0015) || (diff_next <= -0.0015));
 
  245        bool err_end = ((diff_end >= 0.0025) || (diff_end <= -0.0025));
 
  246        bool warn_end = ((diff_end >= 0.0015) || (diff_end <= -0.0015));
 
  247        bool err_begin = ((diff_begin >= 0.0025) || (diff_begin <= -0.0025));
 
  248        bool warn_begin = ((diff_begin >= 0.0015) || (diff_begin <= -0.0015));
 
  249        bool err = ((diff >= 0.0025) || (diff <= -0.0025));
 
  250        bool warn = ((diff >= 0.0015) || (diff <= -0.0015));
 
  252        printf(
"%f, %f, %s%f%s, %d, %f, %s%f%s, %f, %s%f%s, %f, %s%f%s, %d, %s%f%s, %s%zd%s    %s\n",
 
  255               (err_begin ? 
"\033[0;31m" : (warn_begin ? 
"\033[0;33m" : 
"")), diff_begin, ((err_begin||warn_begin) ? 
"\033[0m" : 
""),
 
  258               (err_prev ? 
"\033[0;31m" : (warn_prev ? 
"\033[0;33m" : 
"")), diff_prev, ((err_prev||warn_prev) ? 
"\033[0m" : 
""),
 
  260               (err_next ? 
"\033[0;31m" : (warn_next ? 
"\033[0;33m" : 
"")), diff_next, ((err_next||warn_next) ? 
"\033[0m" : 
""),
 
  262               (err_end ? 
"\033[0;31m" : (warn_end ? 
"\033[0;33m" : 
"")), diff_end, ((err_end||warn_end) ? 
"\033[0m" : 
""),
 
  264               (err ? 
"\033[0;31m" : (warn ? 
"\033[0;33m" : 
"")), diff, ((err||warn) ? 
"\033[0m" : 
""),
 
  265               ((datamap->size() <= 10) ? 
"\033[0;31m" : ((datamap->size() <= 15) ? 
"\033[0;33m" : 
"")), datamap->size(), ((datamap->size() <= 15) ? 
"\033[0m" : 
""),
 
  266               ((diff > maxDelay) ? 
"\033[0;31mSKIPPED\033[0m" : 
"OK"));
 
  273            yDebug() << 
"maxDelay (" << maxDelay << 
") exceeded";
 
  280    for(
int i = 0; i < it_prev->second.size(); ++i) {
 
  282            double x0 = it_prev->second.get(i).asFloat64();
 
  283            double x1 = it_next->second.get(i).asFloat64();
 
  284            double t0 = it_prev->first;
 
  285            double t1 = it_next->first;
 
  291                xx = x0 + (tx - t0)*(
x1 - x0)/(t1 - t0);
 
  294                double v0 = it_prev->second.get(i+6).asFloat64();
 
  295                double v1 = it_next->second.get(i+6).asFloat64();
 
  296                double a = (v1 - v0) / (t1 - t0);
 
  298                if (fabs(v1 - v0) > 30) {
 
  304                    xx = x0 + (tx - t0) * v0;
 
  323            bottle->addFloat64(xx);
 
  325            bottle->add(it_prev->second.get(i));
 
  330    if (it_prev != datamap->begin()) {
 
  331        datamap->erase(datamap->begin(), it_prev);
 
  339bool CamCalibPort::updatePose(
double time)
 
  342    if (!selectBottleFromMap(
time, &m_h_encs_map, &m_curr_h_encs, verbose && !useIMU)) {
 
  349    if (!selectBottleFromMap(
time, &m_t_encs_map, &m_curr_t_encs, verbose && !useIMU)) {
 
  350        if (!useIMU && useTorso) {
 
  356    if (!selectBottleFromMap(
time, &m_imu_map, &m_curr_imu, verbose && useIMU)) {
 
  362    double tix = useTorso ? m_curr_t_encs.get(1).asFloat64()/180.0*
M_PI  : 0; 
 
  363    double tiy = useTorso ? -m_curr_t_encs.get(2).asFloat64()/180.0*
M_PI : 0; 
 
  364    double tiz = useTorso ? -m_curr_t_encs.get(0).asFloat64()/180.0*
M_PI : 0; 
 
  366    double nix = -m_curr_h_encs.get(1).asFloat64()/180.0*
M_PI; 
 
  367    double niy = m_curr_h_encs.get(0).asFloat64()/180.0*
M_PI;  
 
  368    double niz = m_curr_h_encs.get(2).asFloat64()/180.0*
M_PI;  
 
  370    double t =  useEyes ? m_curr_h_encs.get(3).asFloat64()/180.0*
M_PI : 0; 
 
  371    double vs = useEyes ? m_curr_h_encs.get(4).asFloat64()/180.0*
M_PI : 0; 
 
  372    double vg = useEyes ? m_curr_h_encs.get(5).asFloat64()/180.0*
M_PI : 0; 
 
  374    double imu_x = useIMU ? m_curr_imu.get(0).asFloat64()/180.0*
M_PI : 0; 
 
  375    double imu_y = useIMU ? m_curr_imu.get(1).asFloat64()/180.0*
M_PI : 0; 
 
  376    double imu_z = useIMU ? m_curr_imu.get(2).asFloat64()/180.0*
M_PI : 0; 
 
  380    yarp::sig::Vector torso_roll_vector(3);
 
  381    torso_roll_vector(0) = tix;
 
  382    torso_roll_vector(1) = 0;
 
  383    torso_roll_vector(2) = 0;
 
  384    yarp::sig::Matrix torso_roll_dcm = yarp::math::rpy2dcm(torso_roll_vector);
 
  386    yarp::sig::Vector torso_pitch_vector(3);
 
  387    torso_pitch_vector(0) = 0;
 
  388    torso_pitch_vector(1) = tiy;
 
  389    torso_pitch_vector(2) = 0;
 
  390    yarp::sig::Matrix torso_pitch_dcm = yarp::math::rpy2dcm(torso_pitch_vector);
 
  392    yarp::sig::Vector torso_yaw_vector(3);
 
  393    torso_yaw_vector(0) = 0;
 
  394    torso_yaw_vector(1) = 0;
 
  395    torso_yaw_vector(2) = tiz;
 
  396    yarp::sig::Matrix torso_yaw_dcm = yarp::math::rpy2dcm(torso_yaw_vector);
 
  398    yarp::sig::Matrix torso_dcm = (torso_pitch_dcm * torso_roll_dcm) * torso_yaw_dcm;
 
  402    yarp::sig::Vector neck_roll_vector(3);
 
  403    neck_roll_vector(0) = nix;
 
  404    neck_roll_vector(1) = 0;
 
  405    neck_roll_vector(2) = 0;
 
  406    yarp::sig::Matrix neck_roll_dcm = yarp::math::rpy2dcm(neck_roll_vector);
 
  408    yarp::sig::Vector neck_pitch_vector(3);
 
  409    neck_pitch_vector(0) = 0;
 
  410    neck_pitch_vector(1) = niy;
 
  411    neck_pitch_vector(2) = 0;
 
  412    yarp::sig::Matrix neck_pitch_dcm = yarp::math::rpy2dcm(neck_pitch_vector);
 
  414    yarp::sig::Vector neck_yaw_vector(3);
 
  415    neck_yaw_vector(0) = 0;
 
  416    neck_yaw_vector(1) = 0;
 
  417    neck_yaw_vector(2) = niz;
 
  418    yarp::sig::Matrix neck_yaw_dcm = yarp::math::rpy2dcm(neck_yaw_vector);
 
  420    yarp::sig::Matrix neck_dcm = (neck_pitch_dcm * neck_roll_dcm) * neck_yaw_dcm;
 
  424    yarp::sig::Vector eye_pitch_vector(3);
 
  425    eye_pitch_vector(0) = 0;
 
  426    eye_pitch_vector(1) = t;
 
  427    eye_pitch_vector(2) = 0;
 
  428    yarp::sig::Matrix eye_pitch_dcm = yarp::math::rpy2dcm(eye_pitch_vector);
 
  430    yarp::sig::Vector eye_yaw_vector(3);
 
  431    eye_yaw_vector(0) = 0;
 
  432    eye_yaw_vector(1) = 0;
 
  433    eye_yaw_vector(2) = 0;
 
  435        eye_yaw_vector(2) = -(vs + vg/2);
 
  437        eye_yaw_vector(2) = -(vs - vg / 2);
 
  439    yarp::sig::Matrix eye_yaw_dcm = yarp::math::rpy2dcm(eye_yaw_vector);
 
  441    yarp::sig::Matrix eye_dcm = eye_pitch_dcm * eye_yaw_dcm;
 
  445    yarp::sig::Matrix encoders_dcm = (torso_dcm * neck_dcm) * eye_dcm;
 
  446    yarp::sig::Vector encoders_rpy = yarp::math::dcm2rpy(encoders_dcm);
 
  450    yarp::sig::Vector imu_roll_vector(3);
 
  451    imu_roll_vector(0) = imu_x;
 
  452    imu_roll_vector(1) = 0;
 
  453    imu_roll_vector(2) = 0;
 
  454    yarp::sig::Matrix imu_roll_dcm = yarp::math::rpy2dcm(imu_roll_vector);
 
  456    yarp::sig::Vector imu_pitch_vector(3);
 
  457    imu_pitch_vector(0) = 0;
 
  458    imu_pitch_vector(1) = imu_y;
 
  459    imu_pitch_vector(2) = 0;
 
  460    yarp::sig::Matrix imu_pitch_dcm = yarp::math::rpy2dcm(imu_pitch_vector);
 
  462    yarp::sig::Vector imu_yaw_vector(3);
 
  463    imu_yaw_vector(0) = 0;
 
  464    imu_yaw_vector(1) = 0;
 
  465    imu_yaw_vector(2) = imu_z;
 
  466    yarp::sig::Matrix imu_yaw_dcm = yarp::math::rpy2dcm(imu_yaw_vector);
 
  468#if AERONAUTIC_CONVENTION 
  470    yarp::sig::Matrix imu_dcm = (imu_yaw_dcm * imu_roll_dcm) * imu_pitch_dcm;
 
  473    yarp::sig::Matrix imu_dcm = (imu_yaw_dcm * imu_pitch_dcm) * imu_roll_dcm;
 
  476    yarp::sig::Vector imu_rpy = yarp::math::dcm2rpy(imu_dcm);
 
  479        roll  = encoders_rpy(0) * 180.0/
M_PI;
 
  480        pitch = encoders_rpy(1) * 180.0/
M_PI;
 
  481        yaw   = encoders_rpy(2) * 180.0/
M_PI;
 
  483        roll  = imu_rpy(0) * 180.0/
M_PI;
 
  484        pitch = imu_rpy(1) * 180.0/
M_PI;
 
  485        yaw   = imu_rpy(2) * 180.0/
M_PI;
 
  530    string str = rf.check(
"name", Value(
"/camCalib"), 
"module name (string)").asString();
 
  531    setName(str.c_str()); 
 
  533    double maxDelay = rf.check(
"maxDelay", Value(0.010), 
"Max delay between image and encoders").asFloat64();
 
  536    Bottle botConfig(rf.toString());
 
  539    if(botConfig.check(
"group", valGroup, 
"Configuration group to load module options from (string).")) {
 
  540        strGroup = valGroup->asString();
 
  542        if (botConfig.check(strGroup)){
 
  543            Bottle &group=botConfig.findGroup(strGroup,
"Loading configuration from group " + strGroup);
 
  544            botConfig.fromString(group.toString());
 
  546            yError() << 
"Group " << strGroup << 
" not found.";
 
  550        yError (
"There seem to be an error loading parameters (group section missing), stopping module");
 
  554    string calibToolName = botConfig.check(
"projection",
 
  556                                           "Projection/mapping applied to calibrated image [projection|spherical] (string).").asString();
 
  559    if (_calibTool!=NULL) {
 
  560        bool ok = _calibTool->
open(botConfig);
 
  568    if (yarp::os::Network::exists(getName(
"/in"))) {
 
  569        yWarning() << 
"port " << getName(
"/in") << 
" already in use";
 
  571    if (yarp::os::Network::exists(getName(
"/out"))) {
 
  572        yWarning() << 
"port " << getName(
"/out") << 
" already in use";
 
  574    if (yarp::os::Network::exists(getName(
"/conf"))) {
 
  575        yWarning() << 
"port " << getName(
"/conf") << 
" already in use";
 
  577    _prtImgIn.
setSaturation(rf.check(
"saturation",Value(1.0)).asFloat64());
 
  578    _prtImgIn.open(getName(
"/in"));
 
  581    _prtImgIn.
setLeftEye((strGroup == 
"CAMERA_CALIBRATION_LEFT") ? 
true : false);
 
  587    _prtImgIn.useCallback();
 
  588    _prtImgOut.open(getName(
"/out"));
 
  589    _configPort.open(getName(
"/conf"));
 
  591    _prtTEncsIn.open(getName(
"/torso_encs/in"));
 
  594    _prtTEncsIn.useCallback();
 
  596    _prtHEncsIn.open(getName(
"/head_encs/in"));
 
  599    _prtHEncsIn.useCallback();
 
  601    _prtImuIn.open(getName(
"/imu/in"));
 
  604    _prtImuIn.useCallback();
 
  609    _prtImgIn.
rpyPort.open(getName(
"/rpy"));
 
  622    if (_calibTool != NULL){
 
  632    _prtImgIn.interrupt();
 
  633    _prtImgOut.interrupt();
 
  634    _configPort.interrupt();
 
  635    _prtTEncsIn.interrupt();
 
  636    _prtHEncsIn.interrupt();
 
  637    _prtImuIn.interrupt();
 
  641void TorsoEncoderPort::onRead(yarp::os::Bottle &t_encs)
 
  644    this->getEnvelope(s);
 
  645    double time = s.getTime();
 
  651void HeadEncoderPort::onRead(yarp::os::Bottle &h_encs)
 
  654    this->getEnvelope(s);
 
  655    double time = s.getTime();
 
  661void ImuPort::onRead(yarp::os::Bottle &imu)
 
  664    this->getEnvelope(s);
 
  665    double time = s.getTime();
 
  685    if (command.get(0).asString()==
"quit") {
 
  686        reply.addString(
"quitting");
 
  688    } 
else if (command.get(0).asString()==
"sat" || command.get(0).asString()==
"saturation") {
 
  689        double satVal = command.get(1).asFloat64();
 
  692        reply.addString(
"ok");
 
  693    } 
else if (command.get(0).asString()==
"filt") {
 
  695    } 
else if (command.get(0).asString()==
"cf1") {
 
  696         _prtImgIn.
cf1 = command.get(1).asFloat64();
 
  697    } 
else if (command.get(0).asString()==
"cf2") {
 
  698        _prtImgIn.
cf2 = command.get(1).asFloat64();
 
  700        yError() << 
"command not known - type help for more info";
 
virtual bool interruptModule()
 
virtual bool respond(const yarp::os::Bottle &command, yarp::os::Bottle &reply)
 
virtual bool configure(yarp::os::ResourceFinder &rf)
Passes config on to CalibTool.
 
virtual bool updateModule()
 
virtual double getPeriod()
 
void setUseLast(bool useLast)
 
yarp::os::BufferedPort< yarp::os::Bottle > rpyPort
 
void setLeftEye(bool eye)
 
void setUseIMU(bool useIMU)
 
void setSaturation(double satVal)
 
void setTorsoEncoders(double time, const yarp::os::Bottle &t_encs)
 
void setUseTorso(bool useTorso)
 
void setImuData(double time, const yarp::os::Bottle &imu)
 
void setVerbose(const bool sw)
 
void setUseEyes(bool useEyes)
 
void setPointers(yarp::os::BufferedPort< yarp::sig::ImageOf< yarp::sig::PixelRgb > > *_portImgOut, ICalibTool *_calibTool)
 
void setHeadEncoders(double time, const yarp::os::Bottle &h_encs)
 
void setMaxDelay(double delay)