私が作っているプログラムは、はしごに接続されているステッパーモーターを制御することになっています。私が計算したい変数は、はしごのパーセンテージまでの距離を教えてくれます。ステッピングモーターが23400歩歩いたときのはしごは100%です。なぜパーセントを計算できないのですか?
ステップ変数は、モータのステップ信号が送信されているISRルーチンで増分されています。
ここにISRルーチンがあります。可変step_count
として
ISR(TIMER1_COMPA_vect)
{
// Holds next delay period.
unsigned int new_first_step_delay;
// Remember the last step delay used when accelrating.
static int last_accel_delay;
// Counting steps when moving.
static unsigned int step_count = 0;
// Keep track of remainder from new_step-delay calculation to incrase accurancy
static unsigned int rest = 0;
OCR1A = profile.first_step_delay;
switch (profile.run_state)
{
case STOP:
profile.moved_steps = step_count;
// Stop the timer, No clock source
break;
case ACCEL:
digitalWrite(step_pin,!digitalRead(step_pin));
step_count++;
profile.accel_count++;
// Do something
// Chech if we should start decelration.
if (step_count >= profile.decel_start)
{
profile.accel_count = profile.decel_length;
profile.run_state = DECEL;
}
// Chech if we hitted max speed.
else if (new_first_step_delay <= profile.min_time_delay)
{
last_accel_delay = new_first_step_delay;
new_first_step_delay = profile.min_time_delay;
rest = 0;
profile.run_state = RUN;
}
break;
case RUN:
digitalWrite(step_pin,!digitalRead(step_pin));
step_count++;
new_first_step_delay = profile.min_time_delay;
// Do something
if (step_count >= profile.decel_start)
{
profile.run_state = DECEL;
}
break;
case DECEL:
digitalWrite(step_pin,!digitalRead(step_pin));
step_count++;
profile.accel_count++;
// Do something
if(profile.accel_count >= 0)
{
digitalWrite(en_pin,!digitalRead(en_pin));
profile.moved_steps = step_count;
moved_to_position=true;
profile.run_state = STOP;
}
break;
}
profile.first_step_delay = new_first_step_delay;
if(moved_to_position==true)
{
moved_to_position = false;
}
}
私は範囲外でそれを使用できるよう、profile.moved_steps = step_count
に値を格納する理由はISRの範囲内の、それゆえのみ閲覧可能、静的変数です。
profile
は、構造体speed_profile
のインスタンス化であり、グローバル変数としてインスタンス化され、どこでも読み取ることができます。
構造体は、次のように定義されます
typedef struct
{
volatile unsigned char run_state : 3; // Determining the state of the speed profile
volatile unsigned char dir: 1; // Determining the direction the motor has to move - Start being CCW
volatile unsigned int first_step_delay; // Period time for the next timer_delay, determines the acceleration rate.
volatile unsigned int decel_start; // Determines at which step the deceleration should begin.
volatile signed int decel_length; // Set the deceleration length
volatile signed int min_time_delay; //minium time required time_delay for achieving the wanted speed.
volatile signed int accel_count; // counter used when computing step_delay for acceleration/decelleration.
volatile unsigned int moved_steps; // Used by ros to publish current tipper position
volatile unsigned int current_step_position; // contains the current step_position
volatile unsigned int step_counter; //used for debug purpose
}speed_profile;
profile.moved_steps
はパーセンテージを計算するために使用されている、それは常にこの関数内ROSトピックに公開されています。
void compute_speed_profile(signed int motor_steps, unsigned int motor_accel, unsigned int motor_decel, unsigned int motor_speed)
{
while(global_state == false)
{
//do nothing
status_step_count.data = profile.current_step_position;
chatter.publish(&status_step_count);
nh.spinOnce();
moved_to_position = true;
delay(1);
}
//Setting up timer
while(global_state == true) // request received
{ int temp = 0;
cli();
temp = profile.moved_steps; // Keeping ISR disable shortest time possible
sei();
if(profile.dir == CCW)
{
profile.current_step_position -= temp;
}
else
{
profile.current_step_position += temp;
}
status_step_count.data = ((float)(profile.current_step_position/23400.0))*100.0;
chatter.publish(&status_step_count);
if(moved_to_position == false) // Ensures that I am reading the newest variable
{
global_state = false;
}
nh.spinOnce();
delay(1);
}
}
2つのスレッド間の切り替え(1つはglobal_state = stateまたはfalse)。 グローバルノードのステータスは、rosノードが購読しているトピックにメッセージを送信し、モーターが移動した後にglobal_stateがfalseステートに戻り、メッセージを待つときにtrueになります。私はどんな効果を持っていない計算のように思える割合
status_step_count.data = ((float)(profile.current_step_position/23400.0))*100.0;
を計算したいとき
だから問題があります。それはモーターがステップ数ではなくパーセントで戻ってくるのを維持しますか? - なぜ私はかなり不確かなのですか?
大量のコードの問題は、通常、同じ問題を示す[mcve]を作成する方が良い理由です。 – Rakete1111
'%'が実際に行っていることをよりよく理解するために、膨大な量のコード –
[C++算術演算子を参照](http://en.cppreference.com/w/cpp/language/operator_arithmetic)を読む人はいません。 – WhozCraig