<commit_before>/*
 * Pano engine
 *
 * Copyright (C)2016 <NAME>
 *
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
 */

#include "pano.h"

Pano::Pano(Motor& horiz_motor, Motor& vert_motor, Camera& camera,
           int horiz_motor_enable_pin, int vert_motor_enable_pin)
:horiz_motor(horiz_motor),
 vert_motor(vert_motor),
 camera(camera),
 horiz_motor_enable_pin(horiz_motor_enable_pin),
 vert_motor_enable_pin(vert_motor_enable_pin)
{
    pinMode(horiz_motor_enable_pin, OUTPUT);
    pinMode(vert_motor_enable_pin, OUTPUT);
    motorsOff();

    setFOV(360,180);
}
void Pano::setFOV(int horiz_angle, int vert_angle){
    if (horiz_angle && vert_angle && horiz_angle <= 360 && vert_angle <= 180){
        horiz_fov = horiz_angle;
        vert_fov = vert_angle;
    }
}
void Pano::setFocalLength(unsigned focal_length){
    focal_length = camera.setFocalLength(focal_length);
}
void Pano::setShutter(unsigned speed, unsigned pre_delay){
    shutter_delay = speed;
    pre_shutter_delay = pre_delay;
}
void Pano::setShots(unsigned shots){
    shots_per_position = shots;
}
void Pano::setMode(unsigned mode){

}
unsigned Pano::getHorizShots(void){
    return horiz_count;
}
unsigned Pano::getVertShots(void){
    return vert_count;
}
/*
 * Helper to calculate grid fit with overlap
 * @param total_size: entire grid size
 * @param overlap: min required overlap in percent (1-99)
 * @param block_size: ref to initial block size (will be updated)
 * @param count: ref to image count (will be updated)
 */
void Pano::gridFit(int total_size, int overlap, int& block_size, int& count){
    Serial.print("total_size="); Serial.println(total_size);
    Serial.print("block size="); Serial.println(block_size);

    if (block_size <= total_size){
        count = (100*total_size - overlap*block_size - 1) / ((100 - overlap)*block_size);
        block_size = (total_size - block_size + count - 1) / count;
        count++;
    } else {
        count = 1;
    }

    Serial.print("count="); Serial.println(count);
    Serial.print("new block_size="); Serial.println(block_size);
}
/*
 * Calculate shot-to-shot horizontal/vertical head movement,
 * taking overlap into account
 * Must be called every time focal distance or panorama dimensions change.
 */
void Pano::computeGrid(void){
    horiz_move = camera.getHorizFOV();
    gridFit(horiz_fov, MIN_OVERLAP, horiz_move, horiz_count);
    vert_move = camera.getVertFOV();
    gridFit(vert_fov, MIN_OVERLAP, vert_move, vert_count);
}
void Pano::start(void){
    computeGrid();
    motorsOn();
    horiz_motor.setRPM(20); // 60 @ 0.8A, 20 @ 0.3A & 1:16
    vert_motor.setRPM(60); // 180 @ 0.8A. 60 @ 0.3A & 1:16
    // move to start position
    position = 0;
}
void Pano::shutter(void){
    delay(pre_shutter_delay);
    for (unsigned i=shots_per_position; i; i--){
        camera.shutter(shutter_delay);
    }
}
bool Pano::next(void){
    motorsOn(); // temporary

    ++position;

    Serial.print(F("at ")); Serial.println(position);

    if (position % horiz_count){
        // still within current row
        Serial.println(F("  H-->"));
        horiz_motor.rotate(horiz_move*horiz_gear_ratio);
    } else {
        // end of row. reset column
        Serial.println(F("  <--H"));
        horiz_motor.rotate((1-horiz_count)*horiz_move*horiz_gear_ratio);
        if (position / horiz_count < vert_count){
            // still within pano, change row, reset column
            Serial.println(F("  V-->"));
            vert_motor.rotate(-vert_move*vert_gear_ratio);
        } else {
            Serial.println(F("  <--V"));
            vert_motor.rotate((vert_count-1)*vert_move*vert_gear_ratio);
            return false;
        }
    }
    motorsOff(); // temporary
    return true;
}
void Pano::end(void){
    // move to home position<commit_msg>Turn motors off after finishing pano.<commit_after>/*
 * Pano engine
 *
 * Copyright (C)2016 <NAME>
 *
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
 */

#include "pano.h"

Pano::Pano(Motor& horiz_motor, Motor& vert_motor, Camera& camera,
           int horiz_motor_enable_pin, int vert_motor_enable_pin)
:horiz_motor(horiz_motor),
 vert_motor(vert_motor),
 camera(camera),
 horiz_motor_enable_pin(horiz_motor_enable_pin),
 vert_motor_enable_pin(vert_motor_enable_pin)
{
    pinMode(horiz_motor_enable_pin, OUTPUT);
    pinMode(vert_motor_enable_pin, OUTPUT);
    motorsOff();

    setFOV(360,180);
}
void Pano::setFOV(int horiz_angle, int vert_angle){
    if (horiz_angle && vert_angle && horiz_angle <= 360 && vert_angle <= 180){
        horiz_fov = horiz_angle;
        vert_fov = vert_angle;
    }
}
void Pano::setFocalLength(unsigned focal_length){
    focal_length = camera.setFocalLength(focal_length);
}
void Pano::setShutter(unsigned speed, unsigned pre_delay){
    shutter_delay = speed;
    pre_shutter_delay = pre_delay;
}
void Pano::setShots(unsigned shots){
    shots_per_position = shots;
}
void Pano::setMode(unsigned mode){

}
unsigned Pano::getHorizShots(void){
    return horiz_count;
}
unsigned Pano::getVertShots(void){
    return vert_count;
}
/*
 * Helper to calculate grid fit with overlap
 * @param total_size: entire grid size
 * @param overlap: min required overlap in percent (1-99)
 * @param block_size: ref to initial block size (will be updated)
 * @param count: ref to image count (will be updated)
 */
void Pano::gridFit(int total_size, int overlap, int& block_size, int& count){
    Serial.print("total_size="); Serial.println(total_size);
    Serial.print("block size="); Serial.println(block_size);

    if (block_size <= total_size){
        count = (100*total_size - overlap*block_size - 1) / ((100 - overlap)*block_size);
        block_size = (total_size - block_size + count - 1) / count;
        count++;
    } else {
        count = 1;
    }

    Serial.print("count="); Serial.println(count);
    Serial.print("new block_size="); Serial.println(block_size);
}
/*
 * Calculate shot-to-shot horizontal/vertical head movement,
 * taking overlap into account
 * Must be called every time focal distance or panorama dimensions change.
 */
void Pano::computeGrid(void){
    horiz_move = camera.getHorizFOV();
    gridFit(horiz_fov, MIN_OVERLAP, horiz_move, horiz_count);
    vert_move = camera.getVertFOV();
    gridFit(vert_fov, MIN_OVERLAP, vert_move, vert_count);
}
void Pano::start(void){
    computeGrid();
    motorsOn();
    horiz_motor.setRPM(20); // 60 @ 0.8A, 20 @ 0.3A & 1:16
    vert_motor.setRPM(60); // 180 @ 0.8A. 60 @ 0.3A & 1:16
    // move to start position
    position = 0;
}
void Pano::shutter(void){
    delay(pre_shutter_delay);
    for (unsigned i=shots_per_position; i; i--){
        camera.shutter(shutter_delay);
    }
}
bool Pano::next(void){
    motorsOn(); // temporary

    ++position;

    Serial.print(F("at ")); Serial.println(position);

    if (position % horiz_count){
        // still within current row
        Serial.println(F("  H-->"));
        horiz_motor.rotate(horiz_move*horiz_gear_ratio);
    } else {
        // end of row. reset column
        Serial.println(F("  <--H"));
        horiz_motor.rotate((1-horiz_count)*horiz_move*horiz_gear_ratio);
        if (position / horiz_count < vert_count){
            // still within pano, change row, reset column
            Serial.println(F("  V-->"));
            vert_motor.rotate(-vert_move*vert_gear_ratio);
        } else {
            Serial.println(F("  <--V"));
            vert_motor.rotate((vert_count-1)*vert_move*vert_gear_ratio);
            motorsOff(); // temporary
            return false;
        }
    }
    motorsOff(); // temporary
    return true;
}
void Pano::end(void){
    // move to home position
{'fraction_non_alphanumeric': 0.1271617497456765, 'fraction_numerical': 0.014750762970498474, 'mean_word_length': 3.4086322869955157, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '386936', 'n_tokens_mistral': 2766, 'n_tokens_neox': 2588, 'n_words': 606}